Skip to content

[pull] main from fern-api:main#769

Merged
pull[bot] merged 19 commits into
code:mainfrom
fern-api:main
Jun 4, 2026
Merged

[pull] main from fern-api:main#769
pull[bot] merged 19 commits into
code:mainfrom
fern-api:main

Conversation

@pull

@pull pull Bot commented Jun 4, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

tstanmay13 and others added 19 commits June 4, 2026 14:17
…SSE discrimination (#16247)

* fix(java): use IR discriminatorContext instead of name heuristic for SSE discrimination

The SSE discrimination analyzer previously inferred whether a union was
discriminated at the SSE envelope level or inside the data payload by
matching the discriminator's wire name against a hardcoded set of envelope
field names (event, id, retry, data). This misroutes unions whose
discriminator legitimately lives in the data payload but happens to be
named like an SSE envelope field: they were dispatched via the envelope
path and failed to parse.

Read the discrimination level from the IR's discriminatorContext on the
union declaration instead. PROTOCOL means the discriminator is at the SSE
envelope level (envelope dispatch); DATA or absent means the discriminator
is inside the JSON data payload and Jackson handles it. The enum value is
renamed EVENT_LEVEL -> PROTOCOL_LEVEL to match the IR vocabulary.

* chore(seed): regenerate java-sdk SSE fixtures for discriminatorContext fix

Regenerates the server-sent-event-examples and server-sent-events-openapi
fixtures so unions without an explicit protocol discriminatorContext now
parse from the data payload (Stream.fromSse) instead of being dispatched
through the SSE envelope (Stream.fromSseWithEventDiscrimination).

* chore(java): add changelog entry for SSE discrimination fix

* fix(java): pin discriminator property in SSE analyzer data-level tests

The discriminator property flows into the generated Stream call, so the
data-level cases assert it alongside the discrimination type.
…ient name (#16244)

* feat(java): add exported-client-class-name config for docs snippets

* chore(java): add changelog entry for exported-client-class-name

* fix(java): keep wire-test snippets on the internal client class name

Wire tests embed imports extracted from dynamically generated snippets.
With exported-client-class-name set, those snippets imported and
instantiated the exported wrapper class, which does not exist in
generator output — the extracted import would break wire-test
compilation and drop the import the test boilerplate's client field
relies on. Strip the docs-only override from the config passed to the
wire-test snippet generator so its snippets always reference the
generated client.
When the SDK receives JSON with an unknown discriminant value, it now
preserves the raw payload internally rather than silently dropping the
variant data. Re-marshaling the union returns the original bytes, so
new server-introduced variants round-trip losslessly through the SDK.

- Add rawJSON json.RawMessage field to generated union structs
- UnmarshalJSON stores the raw payload
- MarshalJSON returns the preserved payload when the discriminant
  does not match any known variant (instead of erroring)
- validate() allows the unknown-variant case (discriminant set,
  no known field, rawJSON preserved) to round-trip

Behavior for known discriminants and the Accept visitor is unchanged.
Aligns Go with Java, C#, PHP, and TypeScript SDKs which already
support forward-compatible unions.

Fixes FER-10267
Co-authored-by: jsklan <100491078+jsklan@users.noreply.github.com>
…16241)

* fix(cli-generator): update sync-sdk.sh for cli-sdk autobins layout

cli-sdk moved binaries from cli/<name>/ to src/bin/<name>/ (autobins).
The sync script now:
- Excludes src/bin/*/ directories from the src/ rsync
- Sources openapi-fixture from src/bin/openapi-fixture/
- Updates the strip-fixture-tests.py regex to match ../bin/ paths

* fix(cli-generator): update early-exit guard in strip-fixture-tests.py

The fast-path check also needs to match ../bin/ paths, not just
../../cli/, so files with the new include_str! pattern are processed.

* fix: align fast-path guard with FIXTURE_RE regex coverage

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
)

In PHP, false == null evaluates to true (loose comparison), so inside
an 'if ($param != null)' block PHPStan infers the boolean can only be
true, making the ternary '$param ? "true" : "false"' always true.

Switch to !== null (strict comparison) so PHPStan correctly sees both
true and false as possible values.

Removes 'literal' from allowedFailures.
Co-authored-by: iamnamananand996 <31537362+iamnamananand996@users.noreply.github.com>
Co-authored-by: jsklan <100491078+jsklan@users.noreply.github.com>
…zation (#16252)

* fix(php): use ->value and ::from() for enum variants in unions

Union types with enum variants were calling jsonSerialize()/jsonDeserialize()
on the enum value, but PHP enums don't have these methods. Now correctly
uses ->value for serialization and ::from() for deserialization.

Removes circular-references and circular-references-advanced from
allowedFailures. trace remains due to additional PHPDoc + dynamic snippet issues.

* fix(php): keep trace in seed allowedFailures (unrelated PHPStan failures)

* fix(php): update trace fixture output with enum serialization fixes

* fix(php): remove trace from allowedFailures (now passing with enum fix)

* ci: retrigger CI for PR #16252

* fix(php): re-add trace to seed allowedFailures (still fails on unrelated PHPStan errors)
Co-authored-by: iamnamananand996 <31537362+iamnamananand996@users.noreply.github.com>
Co-authored-by: jsklan <100491078+jsklan@users.noreply.github.com>
…16249)

* fix(cli): backfill missing required fields in AI-enhanced examples

When the AI Lambda generates examples from the raw OpenAPI spec, it may not
properly resolve nested allOf chains, producing partial examples missing required
fields. This adds a backfill step that merges any missing fields from the correct
auto-generated example into the AI output.

The AI's realistic values are preserved for fields it provided, while missing
required fields are filled from the auto-generated example (which has the full
set thanks to the recursive mergeAllOfProperties fix in PR #16222).

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: handle Lambda {body: {...}} envelope in backfill

The AI Lambda sometimes wraps its response in a {body: {...}} envelope.
Unwrap before backfilling so missing fields are merged at the correct
nesting level, then re-wrap to preserve the expected structure for
downstream processing.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: align unwrapLambdaBodyEnvelope predicate with downstream unwrap

Drop the Object.keys(value).length === 1 check so the envelope detection
matches writeAiExamplesOverride.ts:136-144 which unwraps whenever 'body'
is present regardless of other keys (e.g. {body: {...}, statusCode: 200}).

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* style: format unwrapLambdaBodyEnvelope per biome

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: disambiguate Lambda envelope from schemas with literal body field

When the original auto-generated example has a 'body' key, the enhanced
result's body key is a real schema field (e.g. GitHub issue comments,
email APIs) — not a Lambda envelope. Only unwrap/rewrap when the original
does NOT have a body key.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: do not re-wrap backfilled value in {body} envelope

The IR path (unwrapExampleValue/filterRequestBody) only handles FDR
{type,value} wrappers, not {body} envelopes. Storing the unwrapped
backfilled value directly ensures both the IR path and the override
file path (which has its own unwrap) see the correct shape.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: cade <info@buildwithfern.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@pull pull Bot locked and limited conversation to collaborators Jun 4, 2026
@pull pull Bot added the ⤵️ pull label Jun 4, 2026
@pull pull Bot merged commit ccbc2ac into code:main Jun 4, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants