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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions