Skip to content

Projection on UnionTypes leads to an Unable to cast Exception #6953

Description

@phebing

Product

Hot Chocolate

Version

13.8.1

Link to minimal reproduction

https://github.com/phebing/HC-UnionType-Projection-Bug

Steps to reproduce

Create a backend Query like

[ExtendObjectType(OperationTypeNames.Query)]
public class Queries
{
    public class Base
    {
        public string C { get; set; }
    }

    public class ChildA : Base
    {
        public string A { get; set; }
    }

    public class ChildB : Base
    {
        public string B { get; set; }
    }

    public class ChildAType : ObjectType<ChildA>
    {
        protected override void Configure(IObjectTypeDescriptor<ChildA> descriptor)
        {
            descriptor.Field(_ => _.A).Type<NonNullType<StringType>>();
        }
    }

    public class ChildBType : ObjectType<ChildB>
    {
        protected override void Configure(IObjectTypeDescriptor<ChildB> descriptor)
        {
            descriptor.Field(_ => _.B).Type<NonNullType<StringType>>();
        }
    }

    public class UnionTestType : UnionType
    {
        protected override void Configure(IUnionTypeDescriptor descriptor)
        {
            base.Configure(descriptor);
            descriptor.Name("UnionTestType");
            descriptor.Type<ChildAType>();
            descriptor.Type<ChildBType>();
        }
    }

    [UseProjection]
    [GraphQLType(typeof(ListType<UnionTestType>))]
    public IQueryable<Base> GetUnionTest()
    {
        var types = new List<Base>();
        return types.AsQueryable();
    }
}

And run a query on it like

query {
  unionTest {
    __typename
    ...on ChildA{
      a
    }
    ... on ChildB {
      b
    }
  }
}

What is expected?

The Query returns the specific Elements and uses a projected DB call to do so.

What is actually happening?

If you have a Query like GetUnionTest that returns an UnionType and you add [UseProjection] then it throws an "Unexpected Execution Error" with the message

"message":  "Unable to cast object of type 'System.Linq.Expressions.Expression1`1[System.Func`2[System.Object,System.Object]]' to type 'System.Linq.Expressions.Expression`1[System.Func`2[omittedNamespace...Queries+Base,omittedNamespace...Queries+Base]]'.",

"stackTrace": "   at HotChocolate.Data.Projections.Expressions.QueryableProjectionScopeExtensions.Project[T](QueryableProjectionScope scope)\n   at HotChocolate.Data.Projections.Expressions.QueryableProjectionContextExtensions.Project[T](QueryableProjectionContext context)\n   at HotChocolate.Data.Projections.Expressions.QueryableProjectionProvider.<CreateApplicator>b__7_0[TEntityType](IResolverContext context, Object input)\n   at HotChocolate.Data.Projections.Expressions.QueryableProjectionProvider.<>c__DisplayClass4_0`1.<<CreateExecutor>g__ExecuteAsync|1>d.MoveNext()\n--- End of stack trace from previous location ---\n   at HotChocolate.Execution.Processing.Tasks.ResolverTask.ExecuteResolverPipelineAsync(CancellationToken cancellationToken)\n   at HotChocolate.Execution.Processing.Tasks.ResolverTask.TryExecuteAsync(CancellationToken cancellationToken)"

Even a query just for the types throws this error

query {
  unionTest {
    __typename
  }
}

In the minimal example I skipped the DB, since the error is also happening on a List.AsQueryable().

The Documentation of Projections is not mentioning if UnionTypes are not supported. So if that is the case, then maybe this should be mentioned.

Relevant log output

[2024-03-01 12:39:34 ERR] An error occurred when resolving /unionTest
System.InvalidCastException: Unable to cast object of type 'System.Linq.Expressions.Expression1`1[System.Func`2[System.Object,System.Object]]' to type 'System.Linq.Expressions.Expression`1[System.Func`2[omittedNamespace...Queries+Base]]'.
    at HotChocolate.Data.Projections.Expressions.QueryableProjectionScopeExtensions.Project[T](QueryableProjectionScope scope)
    at HotChocolate.Data.Projections.Expressions.QueryableProjectionContextExtensions.Project[T](QueryableProjectionContext context)
    at HotChocolate.Data.Projections.Expressions.QueryableProjectionProvider.<CreateApplicator>b__7_0[TEntityType](IResolverContext context, Object input)
    at HotChocolate.Data.Projections.Expressions.QueryableProjectionProvider.<>c__DisplayClass4_0`1.<<CreateExecutor>g__ExecuteAsync|1>d.MoveNext()
 --- End of stack trace from previous location ---
    at HotChocolate.Execution.Processing.Tasks.ResolverTask.ExecuteResolverPipelineAsync(CancellationToken cancellationToken)
    at HotChocolate.Execution.Processing.Tasks.ResolverTask.TryExecuteAsync(CancellationToken cancellationToken)


### Additional context

_No response_

Activity

  1. phebing commented on Mar 7, 2024

    @phebing
    Author

    There seem to be more Issues going on with UnionTypes and Projections (maybe related):
    If I have the UnionType as a property of a ResponseType and the query uses projection, then the __typename is always only one of the types, even if the actual object uses the other type.
    Also in such a setup the query has to ask for the same fields in both types or it will result in an error.
    So with an object ChildA and ChildB a query like

    __typename
    ... on ChildA { c }, 
    ... on ChildB { c }
    

    would work, but you would always have __typename == "ChildA" (or B) but not one of each.

    And

    __typename
    ... on ChildA { a },
    ... on ChildB { b }
    

    would throw an error.

    And if the property is a List of the UnionType, then querying that also results in errors.

    If this should be supported, then I can create an Issue with minimal examples as well, but feels like this is not supported at the moment.

  2. mohamedilyeshel commented on Mar 24, 2025

    @mohamedilyeshel

    Hello @phebing, is there any updates for this issue?, or is there a workaround i could use to solve this?

  3. added this to the HC-15.x.x milestone on Mar 26, 2025
  4. added a commit that references this issue on Feb 27, 2026
    564b162
  5. added a commit that references this issue on Jul 15, 2026
    f550df7
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area: DataIssue is related to filtering, sorting, pagination or projections🌶️ hot chocolate

    Type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions