Skip to content

fix(graphql): rename mutation response wrapper on output-type name collision#55

Merged
Theauxm merged 1 commit into
mainfrom
fix/graphql-response-type-name-collision
May 14, 2026
Merged

fix(graphql): rename mutation response wrapper on output-type name collision#55
Theauxm merged 1 commit into
mainfrom
fix/graphql-response-type-name-collision

Conversation

@Theauxm
Copy link
Copy Markdown
Member

@Theauxm Theauxm commented May 14, 2026

Summary

The mutation response wrapper is normally named {trainName}Response. When a user's output CLR class happens to be named {trainName}Response (e.g. IAddressValidationTrain returning AddressValidationResponse), HotChocolate gets two type registrations claiming the same GraphQL name and schema build fails with "type registered twice."

The fix detects the collision against the set of output ObjectType names and falls back to {trainName}MutationResponse. Trains whose output types follow a different naming convention are unaffected.

The collision needs three things to line up: the train's derived name ends right before where Response would go, AND the user's output CLR class is literally named {TrainName}Response. Easy footgun because FooResponse is a common convention for output DTOs and IFooTrainFoo is the standard derivation.

Test plan

  • New regression tests in TrainTypeModuleTests.cs under Response Type Name Collision region:
    • Collision case → wrapper renamed; both types present in module output
    • Collision case → real schema build via IRequestExecutorResolver succeeds (the actual failure mode)
    • Non-collision case → default {trainName}Response name preserved
    • Cross-train collision (TrainA's wrapper name matches TrainB's output class name) → still renamed
    • Query train with same shape → no rename (queries don't get wrappers)
  • Full Trax.Api.Tests suite passes (1348 tests)
  • csharpier-clean
  • Companion docs PR in Trax.Docs documenting the fallback

…llision

The mutation response wrapper is normally named "{trainName}Response". When a
user's output CLR class happens to be named "{trainName}Response" (e.g.
IAddressValidationTrain returning AddressValidationResponse), HotChocolate gets
two type registrations claiming the same GraphQL name and schema build fails.

Detect the collision against the set of output ObjectType names and fall back
to "{trainName}MutationResponse" so the schema can build. Trains whose output
types follow a different naming convention are unaffected.
@Theauxm Theauxm merged commit a1f1673 into main May 14, 2026
1 check passed
@Theauxm Theauxm deleted the fix/graphql-response-type-name-collision branch May 14, 2026 20:58
@codecov
Copy link
Copy Markdown

codecov Bot commented May 14, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@traxsharp
Copy link
Copy Markdown

traxsharp Bot commented May 14, 2026

This PR is included in version 1.30.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant