Skip to content

fix(cli): preserve variant-inherited keys in discriminated union example validation#16157

Merged
patrickthornton merged 3 commits into
mainfrom
patrick/cli/fix-union-example-extends-overlap
Jun 1, 2026
Merged

fix(cli): preserve variant-inherited keys in discriminated union example validation#16157
patrickthornton merged 3 commits into
mainfrom
patrick/cli/fix-union-example-extends-overlap

Conversation

@patrickthornton
Copy link
Copy Markdown
Contributor

@patrickthornton patrickthornton commented Jun 1, 2026

Closes FER-10932

Summary

  • fern check was emitting spurious Example is missing required property "<key>" errors for discriminated-union examples when the union had inferred base-properties AND the variants also inherited those same property keys via their extends chain.
  • When the union validator constructed the variant-level example, it stripped every key that matched the union's base-properties — but the variant still required those keys via its own extends, so the variant validator then flagged them as missing.
  • Fix: keep keys the variant itself declares (own properties or inherited via extends) when building the example handed to variant-level validation. Keys owned exclusively by the union are still filtered as before.

Example

Surfaced on an Auth0 spec where ConnectionResponseContent is a 55-variant discriminated union with infer-discriminated-union-base-properties: true. The inferred base-properties (id, name, display_name, …) overlap with what each variant inherits via extends: ConnectionResponseCommonCreateConnectionCommonConnectionCommon. Before the fix, fern check emitted 9 false errors; after, it's clean:

# before
[error] Example is missing required property "response.body.id"
[error] Example is missing required property "response.body.name"
[error] Example is missing required property "response.body.connections.0.id"
...
Found 9 errors and 19 warnings.

# after
Found 0 errors and 19 warnings.

The minimal repro is captured as a fixture in this PR. Variants Dog/Cat both extends: AnimalBase (which declares id, name), and the union Animal declares the same two keys under base-properties:

AnimalBase:
  properties:
    id: string
    name: string
Dog:
  extends: AnimalBase
  properties:
    breed: string
Animal:
  discriminant: kind
  base-properties:
    id: string
    name: string
  union:
    dog: Dog
  examples:
    - value: { kind: dog, id: rex-1, name: Rex, breed: corgi }

Pre-fix, the example above produced false Example is missing required property "id" / "name" violations; post-fix it validates cleanly. A deliberately-broken example (missing id) still surfaces the violation, confirming the validator isn't going lax.

Test plan

  • New regression fixture valid-example-type/fixtures/union-with-extends-overlap/ + test case asserts only the deliberately-invalid example produces a violation
  • Reverting the fix locally makes the new test fail; restoring it makes it pass
  • All 70 existing @fern-api/fern-definition-validator tests still pass
  • fern check against the original auth0 reproduction goes from 9 errors to 0

🤖 Generated with Claude Code


Open in Devin Review

Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@patrickthornton patrickthornton self-assigned this Jun 1, 2026
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 3 additional findings.

Open in Devin Review

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 1, 2026

Docs Generation Benchmark Results

Comparing PR branch against median of 5 nightly run(s) on main (latest: 2026-06-01T05:35:53Z).

Fixture main PR Delta
docs 230.6s (n=5) 221.4s (35 versions) -9.2s (-4.0%)

Docs generation runs fern generate --docs --preview end-to-end against the benchmark fixture with 35 API versions (each version: markdown processing + OpenAPI-to-IR + FDR upload).
Delta is computed against the nightly baseline on main.
Baseline from nightly run(s) on main (latest: 2026-06-01T05:35:53Z). Trigger benchmark-baseline to refresh.
Last updated: 2026-06-01 20:40 UTC

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 1, 2026

SDK Generation Benchmark Results

Comparing PR branch against median of 5 nightly run(s) on main (latest: 2026-06-01T05:35:53Z).

Full benchmark table (click to expand)
Generator Spec main (generator) main (E2E) PR (generator) Delta
csharp-sdk square 73s (n=5) 110s (n=5) 63s -10s (-13.7%)
go-sdk square 136s (n=5) 286s (n=5) 130s -6s (-4.4%)
java-sdk square 225s (n=5) 273s (n=5) 233s +8s (+3.6%)
php-sdk square 59s (n=5) 81s (n=5) 50s -9s (-15.3%)
python-sdk square 137s (n=5) 236s (n=5) 130s -7s (-5.1%)
ruby-sdk-v2 square 90s (n=5) 125s (n=5) 88s -2s (-2.2%)
rust-sdk square 167s (n=5) 170s (n=5) 166s -1s (-0.6%)
swift-sdk square 55s (n=5) 745s (n=5) 53s -2s (-3.6%)
ts-sdk square 229s (n=5) 234s (n=5) 223s -6s (-2.6%)

main (generator): generator-only time via --skip-scripts (includes Docker image build, container startup, IR parsing, and code generation — this is the same Docker-based flow customers use via fern generate). main (E2E): full customer-observable time including build/test scripts (nightly baseline, informational). Delta is computed against generator-only baseline.
⚠️ = generation exited with a non-zero exit code (timing may not reflect a successful run).
Baseline from nightly runs on main (latest: 2026-06-01T05:35:53Z). Trigger benchmark-baseline to refresh.
Last updated: 2026-06-01 20:42 UTC

@patrickthornton patrickthornton merged commit 8cbd326 into main Jun 1, 2026
218 checks passed
@patrickthornton patrickthornton deleted the patrick/cli/fix-union-example-extends-overlap branch June 1, 2026 22:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants