ChilliCream / ChilliCream/graphql-platform

HotChocolate code-first triple-nested array throws SchemaException

Open
#8,723 4 comments 8 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

Product

Hot Chocolate

Version

15.1.10

Link to minimal reproduction

https://github.com/denys-vynohradov-saltykov/hot-chocolate-nested-list-error-poc

Steps to reproduce
  1. Create web project with package references HotChocolate.AspNetCore and HotChocolate.Types.Analyzers
  2. Query.cs:
[QueryType]
public class Query
{
    [GraphQLName("coordinates")]
    [GraphQLType<NonNullType<ListType<NonNullType<ListType<NonNullType<ListType<FloatType>>>>>>>]
    public double[][][] GetCoordinates()
    {
        return
        [
            [
                [
                    10d,
                    20d
                ]
            ]
        ];
    }
}
  1. Program.cs:
var builder = WebApplication.CreateBuilder(args);

builder.AddGraphQL()
    .InitializeOnStartup()
    .AddPoCTypes();

var app = builder.Build();

app.MapGraphQL("/graphql", schemaName: null);
app.MapGraphQLSchema("/graphql/schema");

app.Run();
  1. Run project
What is expected?
  • Project started successfully
  • when you navigate into /graphql/ -> schema -> SDL you should see schema
type Query {
  coordinates: [[[Float!]!]!]!
}
What is actually happening?

Exception is thrown

HotChocolate.SchemaException: For more details look at the `Errors` property.

1. Unable to resolve type reference `ListType<ListType<ListType<FloatType>!>!>!`. (HotChocolate.Types.ObjectType)

   at HotChocolate.Configuration.RegisteredType.GetType[T](TypeReference typeRef)
   at HotChocolate.Types.OutputFieldBase.OnCompleteField(ITypeCompletionContext context, ITypeSystemMember declaringMember, OutputFieldDefinitionBase definition)
   at HotChocolate.Types.OutputFieldBase.OnCompleteField(ITypeCompletionContext context, ITypeSystemMember declaringMember, FieldDefinitionBase definition)
   at HotChocolate.Types.FieldBase.CompleteField(ITypeCompletionContext context, ITypeSystemMember declaringMember)
   at HotChocolate.Types.FieldBase.HotChocolate.Types.Helpers.IFieldCompletion.CompleteField(ITypeCompletionContext context, ITypeSystemMember declaringMember)
   at HotChocolate.Internal.FieldInitHelper.CompleteFieldsInternal[TField](ITypeCompletionContext context, ITypeSystemMember declaringMember, TField[] fields)
   at HotChocolate.Internal.FieldInitHelper.CompleteFieldsInternal[TFieldDefinition,TField](ITypeCompletionContext context, ITypeSystemMember declaringMember, IEnumerable`1 fieldDefinitions, Func`3 fieldFactory, Int32 fieldCount)
   at HotChocolate.Internal.FieldInitHelper.CompleteFields[TFieldDefinition,TField](ITypeCompletionContext context, ITypeSystemMember declaringMember, IReadOnlyList`1 fieldDefs, Func`3 fieldFactory)
   at HotChocolate.Types.ObjectType.OnCompleteFields(ITypeCompletionContext context, ObjectTypeDefinition definition)
   at HotChocolate.Types.ObjectType.OnCompleteType(ITypeCompletionContext context, ObjectTypeDefinition definition)
   at HotChocolate.Types.TypeSystemObjectBase`1.CompleteType(ITypeCompletionContext context)
   at HotChocolate.Configuration.TypeInitializer.CompleteType(RegisteredType registeredType)
   at HotChocolate.Configuration.TypeInitializer.<CompleteTypes>b__33_0(RegisteredType type)
   at HotChocolate.Configuration.TypeInitializer.ProcessTypes(TypeDependencyFulfilled fulfilled, Func`2 action)
   at HotChocolate.Configuration.TypeInitializer.CompleteTypes()
   at HotChocolate.Configuration.TypeInitializer.Initialize()
   at HotChocolate.SchemaBuilder.Setup.InitializeTypes(SchemaBuilder builder, IDescriptorContext context, IReadOnlyList`1 types)
   at HotChocolate.SchemaBuilder.Setup.Create(SchemaBuilder builder, LazySchema lazySchema, IDescriptorContext context)
   at HotChocolate.SchemaBuilder.Create(IDescriptorContext context)
   at HotChocolate.SchemaBuilder.HotChocolate.ISchemaBuilder.Create(IDescriptorContext context)
   at HotChocolate.Execution.RequestExecutorResolver.CreateSchemaAsync(ConfigurationContext context, RequestExecutorSetup setup, RequestExecutorOptions executorOptions, IServiceProvider schemaServices, TypeModuleChangeMonitor typeModuleChangeMonitor, CancellationToken cancellationToken)
   at HotChocolate.Execution.RequestExecutorResolver.CreateSchemaServicesAsync(ConfigurationContext context, RequestExecutorSetup setup, TypeModuleChangeMonitor typeModuleChangeMonitor, CancellationToken cancellationToken)
   at HotChocolate.Execution.RequestExecutorResolver.CreateRequestExecutorAsync(String schemaName, Boolean isInitialCreation, CancellationToken cancellationToken)
   at HotChocolate.Execution.RequestExecutorResolver.GetRequestExecutorAsync(String schemaName, CancellationToken cancellationToken)
   at HotChocolate.Execution.RequestExecutorResolver.<WarmupAsync>g__WarmupSchemaAsync|40_0(String schemaName, CancellationToken cancellationToken)
   at HotChocolate.Execution.RequestExecutorResolver.WarmupAsync(CancellationToken cancellationToken)
   at HotChocolate.AspNetCore.Warmup.RequestExecutorWarmupService.StartAsync(CancellationToken cancellationToken)
   at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>b__14_1(IHostedService service, CancellationToken token)
   at Microsoft.Extensions.Hosting.Internal.Host.ForeachService[T](IEnumerable`1 services, CancellationToken token, Boolean concurrent, Boolean abortOnFirstException, List`1 exceptions, Func`3 operation)
   at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)
   at Program.<Main>$(String[] args)
Relevant log output

Additional context

There is a hardcoded limit to how many nested lists HotChocolate allows
https://github.com/ChilliCream/graphql-platform/blob/ce7a74a2edb7f0a66dd6cd84dedd39492c3a8782/src/HotChocolate/Core/src/Types/Internal/TypeInfo.cs#L185

Why do we need triple-nested arrays in the schema:

Known workaround is to introduce custom scalar that represents float array

"""
Array of floating point numbers
For example: [3.14, 2.7]
"""
scalar Position

type Query {
  coordinates: [[Position!]!]!
}

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.

Research direction

Start with the linked minimal reproduction and inspect TypeInfo.cs around line 185, where the hardcoded nested-list limit is noted. Run the reproduction with HotChocolate 15.1.10 and confirm the SchemaException for the triple-nested array. Done means the project starts and the schema exposes coordinates as [[[Float!]!]!]! without the exception.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, graphql
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.