ChilliCream / ChilliCream/graphql-platform
Missing deserialization for fragments in query that has the same field multiple times
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 5.8k
- Forks
- 810
- Avg merge
- 15h 39m
- Merged PRs (30d)
- 98
Description
Is there an existing issue for this?
- I have searched the existing issues
Product
Strawberry Shake
Describe the bug
This issue is a bit tricky to describe, please bear with me:
When generating client code for a query that requests the same interface-typed field multiple times (with different arguments, type fragments, and field aliases), the client only includes proper deserialization for the fragment types in whichever field selection is defined first, which causes factory errors.
Steps to reproduce
For example, given a type with an interface-typed field that takes a parameter:
type Example {
someField(someParameter: String!): ISomeInterface
}
When querying the field multiple times with different arguments and fragments:
query GetMultiple {
example {
firstAlias: someField("foo") {
... on FirstInterfaceImplementation { someString }
}
secondAlias: someField("bar") {
... on SecondInterfaceImplementation { someNumber }
}
}
}
The generated client will only include deserialization for FirstInterfaceImplementation and will return an error when trying to deserialize data for SecondInterfaceImplementation (this stack trace might not be exactly accurate, I hand-edited it to replace my real identifiers with the example ones):
StrawberryShake.ClientError
{
Code = "SS1000",
Exception = System.ArgumentNullException with message "Value cannot be null."
at Example.GraphQL.Generated.State.GetMultipleResultFactory.MapIGetMultiple_Example_SecondAlias(IISomeInterfaceData data)
at Example.GraphQL.Generated.State.GetMultipleResultFactory.MapIGetMultiple_Example(ExampleData data)
at Example.GraphQL.Generated.State.GetMultipleResultFactory.Create(IOperationResultDataInfo dataInfo, IEntityStoreSnapshot snapshot)
at StrawberryShake.OperationResultBuilder`1.Build(Response`1 response),
Extensions = {["StackTrace"] = "omitted for brevity"},
Locations = <null>,
Message = "Value cannot be null.",
Path = <null>
}
I've found that we can work around this problem by specifying all desired fragment types in the first selection of the interface-typed field:
query GetMultiple {
example {
firstAlias: someField("foo") {
... on FirstInterfaceImplementation { someString }
# This is included here just so it gets included in code generation
# and can be deserialized in the other field selection below
... on SecondInterfaceImplementation { someNumber }
}
secondAlias: someField("bar") {
... on SecondInterfaceImplementation { someNumber }
}
}
}
Relevant log output
No response
Additional Context?
No response
Version
13.1.0
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the issue with the GraphQL query in the report against Strawberry Shake 13.1.0, then inspect the generated client and GetMultipleResultFactory deserialization paths. Verify that repeated selections of the interface-typed field retain fragment deserialization for both aliases, and confirm that the generated client no longer raises the reported factory error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100