Skip to content

Tracking: Strawberry Shake fragment/codegen fixes from differential fuzzing (PRs #7-#12) #13

Description

@cliedeman

Tracking: Strawberry Shake fragment/codegen fixes from differential fuzzing

Consolidated tracker for a batch of Strawberry Shake code-generation findings, their fixes, related upstream issues, and verification against upstream vnext. Fix branches are based on main (which mirrors upstream ChilliCream/graphql-platform), so each PR is an isolated, upstream-style change.

How found: a differential codegen fuzzer (graphql-js validity oracle → real CSharpGenerator.Generate(...) → Roslyn-compile of the output). A finding = a spec-valid document that Strawberry Shake throws on, errors on, or emits non-compiling/wrong code for. Targets derived from stackworx/relay-extractor. Harness + write-up: branch test/strawberry-shake-codegen-fuzz (FINDINGS.md). Companion HotChocolate-validator findings: #6.


Status at a glance

Fixes shipped (each TDD-first: failing test → fix → PR)

# Item PR Status In vnext ChilliCream#9977? Upstream
1 Generator throw: composite field selected directly and via a fragment #9 ✅ fixed ❌ still broken new (unreported)
2 CS0528: same named fragment spread ≥2× #7 ✅ fixed ❌ still broken new (unreported)
3 Inline-fragment order / entity referenced twice drops data #11 ✅ fixed ❌ still broken Fixes ChilliCream#8063
4 Union members via a named fragment → empty classes #8 ✅ fixed ❌ still broken Fixes ChilliCream#5992
5 Same fragment across operations → duplicate per-op models #10 🟡 characterizing test + analysis only ❌ still broken Relates ChilliCream#6873
6 Unknown __typename throws at runtime #12 ✅ fixed ❌ still broken Fixes ChilliCream#6415

Second batch — duplicate-member family (shipped)

Item PR Status Upstream
Multiple uploads / file inputs → duplicate members (CS0128 'u' + duplicate MapFilesFromType<T>) #14 ✅ fixed Fixes ChilliCream#9559, ChilliCream#7852
Schema inheritance → "base class already defined" #15 ✅ already fixed on main → regression guard Relates ChilliCream#5593

Verified already-fixed on main (no action needed)


Detail (shipped fixes)

  1. fix(strawberryshake): resolve output type for composite field selected directly and via fragment #9 — a composite field selected directly + via a fragment threw InvalidOperationException: Could not find an output type for the specified field syntax. Root cause: FieldCollector merges duplicate selections in document order while FragmentHelper.CollectFields processes inline fragments first; they disagree on the canonical FieldNode and OperationModel.TryGetFieldResultType's reference-equality lookup misses. Fix registers the merged-away selection sets. 194 passed, no existing snapshot changed.
  2. fix(strawberryshake): dedupe duplicate fragment spreads in interface list (CS0528) #7...UF ...UF listed the fragment interface twice (: IUF, IUF) → CS0528. Root cause: FragmentHelper.CreateImplements adds the cached interface once per spread. Fix dedupes. 195 passed.
  3. fix(strawberryshake): preserve entity fields across differing selection sets (#8063) #11 — entity referenced twice with differing selection sets had fields overwritten with default! by the JSON result builder. Fix hoists ctor args + merges preserved fields in JsonResultBuilderGenerator_UpdateEntity.cs. Aligns with upstream draft Adjust result builder to not return incomplete data from the entity store ChilliCream/graphql-platform#8595. 47 snapshots + 13 clients regenerated.
  4. fix(strawberry-shake): populate union member classes for fragment selections #8 — union members selected via a named fragment on the union got empty classes. Root cause: FragmentHelper.CollectFields didn't descend into named-fragment nodes with an abstract type condition. 14-line fix.
  5. test(strawberry-shake): characterize shared-fragment model naming gap (#6873) #10 — same fragment across two operations generates divergent GetA_* / GetB_* models (only the fragment interface is shared). Full fix is large/risky (operation+path-keyed names, no cross-op registry, ~86 snapshots); ships a characterizing test + scope analysis instead, no production change.
  6. fix(strawberryshake): degrade gracefully on unknown abstract type at runtime #12 — unknown union/interface __typename made the result builder throw new NotSupportedException(). Fix makes the per-__typename dispatch nullability-aware (degrade to null for nullable positions) across JsonResultBuilderGenerator*. 73 snapshots + 13 clients regenerated.

Merge-order note: #7 & #8 both touch FragmentHelper.cs (different methods); #11 & #12 both touch JsonResultBuilderGenerator* and regenerate large snapshot sets (47 and 73) — whichever of #11/#12 merges second needs its snapshots re-regenerated.


vnext (ChilliCream#9977) verification

Ran every repro against the StrawberryShake vnext PR head (a724f9b282). vnext fixes none of the six (see the "In vnext ChilliCream#9977?" column and the full comment). Caveat: that is an early PR head; vnext may address some as it matures. As of that head, all fork PRs remain relevant.


Backlog — related open defects found in the upstream sweep (not yet addressed)

Findings 1 & 2 confirmed unreported upstream (exhaustive open+closed search). Full sweep: comment.


Checklist

— Claude
🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions