graphql-platform icon indicating copy to clipboard operation
graphql-platform copied to clipboard

@defer inside @stream makes HC fail with Unexpected Execution Error

Open RohrerF opened this issue 1 month ago • 1 comments

Product

Hot Chocolate

Version

15.1.11 (also reproducable in v16)

Link to minimal reproduction

https://github.com/RohrerF/hc-stream-defer-issue

Steps to reproduce

Fire a query containing @defer inside @stream

Example:

query{
  books @stream{
    title
    ...bookAuthor @defer
  }
}

fragment bookAuthor on Book{
  author{
    name
  }
}

sample code to achieve that schema:


[QueryType]
public static class Query
{
    public static async IAsyncEnumerable<Book> GetBooks()
    {
        for (int i = 0; i < 42; i++)
        {
            yield return new Book("C# in depth." + i);
            await Task.Delay(TimeSpan.FromSeconds(1));
        }
    }
}

[ExtendObjectType<Book>]
public static class BookTypeExtensions
{
    public static async Task<Author> GetAuthor()
    {
        await  Task.Delay(TimeSpan.FromSeconds(1));
        return new Author("Jon Skeet");
    }
}

public record Author(string Name);
public record Book(string Title);

var builder = WebApplication.CreateBuilder(args);

builder.AddGraphQL().AddTypes().ModifyOptions(o =>
{
    o.EnableDefer = true;
    o.EnableStream = true;
    o.RemoveUnreachableTypes = true;
});

var app = builder.Build();

app.MapGraphQL();

app.RunWithGraphQLCommands(args);

What is expected?

@stream and @defer work together

What is actually happening?

{
  "message": "Unexpected Execution Error",
  "locations": [
    {
      "line": 2,
      "column": 3
    }
  ],
  "path": [
    "books"
  ],
  "extensions": {
    "message": "Cannot build path from an uninitialized field.",
    "stackTrace": "   at HotChocolate.Execution.Processing.PathHelper.Build(Object[] segments, ResultData& parent, Int32 start)\n   at HotChocolate.Execution.Processing.PathHelper.CreatePath(ResultData parent)\n   at HotChocolate.Execution.Processing.PathHelper.CreatePathFromContext(ObjectResult parent)\n   at HotChocolate.Execution.Processing.Tasks.ResolverTaskFactory.EnqueueOrInlineResolverTasks(ValueCompletionContext context, ObjectType parentType, ResultData parentResult, Int32 parentIndex, Object parent, ISelectionSet selectionSet)\n   at HotChocolate.Execution.Processing.ValueCompletion.CompleteCompositeValue(ValueCompletionContext context, ISelection selection, IType type, ResultData parent, Int32 index, Object result)\n   at HotChocolate.Execution.Processing.ValueCompletion.Complete(ValueCompletionContext context, ISelection selection, IType type, ResultData parent, Int32 index, Object result)\n   at HotChocolate.Execution.Processing.Tasks.ResolverTaskFactory.CompleteInline(OperationContext operationContext, MiddlewareContext resolverContext, ISelection selection, IType type, Int32 responseIndex, ObjectResult parentResult, Object value, List`1 bufferedTasks)"
  }
},

Relevant log output


Additional context

No response

RohrerF avatar Nov 18 '25 10:11 RohrerF

We are swapping out the defer implementation in 16 at the moment. The new implementation is based on the new defer and stream spec proposal. Will take probably 3 more weeks.

michaelstaib avatar Nov 18 '25 14:11 michaelstaib