ChilliCream / ChilliCream/graphql-platform

Error when using $defer with incrementalSpec=v0.1

Open
#10,349 0 comments 0 reactions 1 assignee View on GitHub

@michaelstaib is already working on this.

Since Sep 9, 2026.

🌶️ hot chocolate
Dominant language
C#
Stars
5.8k
Forks
810
Avg merge
15h 39m
Merged PRs (30d)
98

Description

Product

Hot Chocolate

Version

16.6.3

Link to minimal reproduction

https://github.com/srollinet/HotChocolate.IncrementalResultFormatAdapters.BugMinimalRepro

Steps to reproduce
  1. Start the server
  2. In Nitro, set header Accept with value application/json, multipart/mixed; incrementalSpec=v0.1
  3. Execute the following query:
query {
  products {
    nodes {
      id
      ...ProductItemFragment @defer(label: "ProductsQuery$defer$productDetails")
    }
  }
}

fragment ProductItemFragment on Product {
  productNumber
}
What is expected?

Query works, like in version 15

{
  "data": {
    "products": {
      "nodes": [
        {
          "id": "1",
          "productNumber": 1001
        },
        {
          "id": "2",
          "productNumber": 1002
        },
        {
          "id": "3",
          "productNumber": 1003
        }
      ]
    }
  }
}
What is actually happening?

Sometimes, the result is empty, sometimes it's partial.

When receiving a partial result, patch1 is ok

{
  "data": {
    "products": {
      "nodes": [
        {
          "id": "1"
        },
        {
          "id": "2"
        },
        {
          "id": "3"
        }
      ]
    }
  }
}

Then patch2 fails

{
  "name": "ServerParseError",
  "statusCode": 200,
  "statusText": "OK",
  "bodyText": ""
}
Relevant log output
fail: Microsoft.AspNetCore.Server.Kestrel[13]
      Connection id "0HNO9ONKK0TT6", Request id "0HNO9ONKK0TT6:00000002": An unhandled exception was thrown by the application.
      System.InvalidOperationException: The requested operation requires an element of type 'Object', but the target element has type 'Array'.
         at System.Text.Json.ThrowHelper.ThrowJsonElementWrongTypeException(JsonTokenType expectedType, JsonTokenType actualType)
         at System.Text.Json.JsonDocument.TryGetNamedPropertyValue(Int32 index, ReadOnlySpan`1 propertyName, JsonElement& value)
         at System.Text.Json.JsonElement.TryGetProperty(String propertyName, JsonElement& value)
         at HotChocolate.Transport.Formatters.IncrementalRfc1ResultFormatAdapter.WriteMergedObject(JsonWriter writer, OperationResultFormatterContext context, Path path, JsonElement patchObject, DeferSelectionTree selection)
         at HotChocolate.Transport.Formatters.IncrementalRfc1ResultFormatAdapter.TryCreateMergedData(OperationResultFormatterContext context, Path pendingPath, Path path, String label, JsonDocument patchDocument, ReadOnlyMemorySegment& mergedData, Path& mergedPath)
         at HotChocolate.Transport.Formatters.IncrementalRfc1ResultFormatAdapter.WriteIncremental(JsonWriter writer, OperationResult result, JsonSerializerOptions options, OperationResultFormatterContext context)
         at HotChocolate.Transport.Formatters.JsonResultFormatter.Format(OperationResult result, JsonWriter writer, Boolean useIncrementalRfc1, OperationResultFormatterContext& context)
         at HotChocolate.Transport.Formatters.JsonResultFormatter.FormatInternal(OperationResult result, IBufferWriter`1 bufferWriter, Boolean useIncrementalRfc1, OperationResultFormatterContext& context)
         at HotChocolate.Transport.Formatters.JsonResultFormatter.Format(OperationResult result, IBufferWriter`1 writer, Boolean useIncrementalRfc1, OperationResultFormatterContext& context)
         at HotChocolate.Transport.Formatters.MultiPartResultFormatter.MessageHelper.WritePayload(IBufferWriter`1 writer, OperationResult result, JsonResultFormatter payloadFormatter, Boolean useIncrementalRfc1, OperationResultFormatterContext& context)
         at HotChocolate.Transport.Formatters.MultiPartResultFormatter.FormatResponseStreamAsync(IResponseStream responseStream, PipeWriter writer, Boolean useIncrementalRfc1, CancellationToken ct)
         at HotChocolate.Transport.Formatters.MultiPartResultFormatter.FormatResponseStreamAsync(IResponseStream responseStream, PipeWriter writer, Boolean useIncrementalRfc1, CancellationToken ct)
         at HotChocolate.Transport.Formatters.MultiPartResultFormatter.FormatResponseStreamAsync(IResponseStream responseStream, PipeWriter writer, Boolean useIncrementalRfc1, CancellationToken ct)
         at HotChocolate.AspNetCore.Formatters.DefaultHttpResponseFormatter.FormatInternalAsync(HttpResponse response, IExecutionResult result, Nullable`1 proposedStatusCode, FormatInfo format, AcceptMediaType acceptMediaType, CancellationToken cancellationToken)
         at HotChocolate.AspNetCore.Formatters.DefaultHttpResponseFormatter.FormatAsync(HttpResponse response, IExecutionResult result, AcceptMediaType[] acceptMediaTypes, Nullable`1 proposedStatusCode, CancellationToken cancellationToken)
         at HotChocolate.AspNetCore.HttpPostMiddlewareBase.HandleRequestAsync(HttpContext context, ExecutorSession session, CancellationToken ct)
         at HotChocolate.AspNetCore.HttpPostMiddlewareBase.HandleRequestAsync(HttpContext context, ExecutorSession session, CancellationToken ct)
         at HotChocolate.AspNetCore.HttpPostMiddlewareBase.InvokeAsync(HttpContext context)
         at HotChocolate.AspNetCore.MiddlewareFactory.<>c__DisplayClass0_0.<<CreateCancellationMiddleware>b__1>d.MoveNext()
      --- End of stack trace from previous location ---
         at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
         at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
         at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
Additional context

In my quick analysis, the problem happens in IncrementalRfc1ResultFormatAdapter.TryCreateMergedData https://github.com/ChilliCream/graphql-platform/blob/7ce54d90aaa724519fa10680408e788717154fab/src/HotChocolate/AspNetCore/src/Transport.Formatters/IncrementalResultFormatAdapters.cs#L213-L215

relativePath has value [0]. So, in WriteWrappedPatch, patch is wrapped in an array

https://github.com/ChilliCream/graphql-platform/blob/7ce54d90aaa724519fa10680408e788717154fab/src/HotChocolate/AspNetCore/src/Transport.Formatters/IncrementalResultFormatAdapters.cs#L156-L167

And later, in WriteMergedObject, TryGetProperty throws because patchObject is an array
https://github.com/ChilliCream/graphql-platform/blob/7ce54d90aaa724519fa10680408e788717154fab/src/HotChocolate/AspNetCore/src/Transport.Formatters/IncrementalResultFormatAdapters.cs#L386-L390

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.