Skip to content

Preserve SSE data schema identifier in OpenAPI output - #2495

Closed
kitlangton wants to merge 4 commits into
Effect-TS:mainfrom
kitlangton:fix-streamsse-data-identifier
Closed

Preserve SSE data schema identifier in OpenAPI output#2495
kitlangton wants to merge 4 commits into
Effect-TS:mainfrom
kitlangton:fix-streamsse-data-identifier

Conversation

@kitlangton

@kitlangton kitlangton commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

What

HttpApiSchema.StreamSse({ data }) encodes the SSE data field as a JSON string (Schema.fromJsonString(data)). In the generated OpenAPI spec, that string wrapper was claiming the data schema's identifier, pushing the decoded schema to a suffixed name.

For a data schema with identifier: "MyEvent":

Before:  MyEvent  = { type: "string", ... }      ← the JSON wrapper (wrong)
         MyEvent1 = { type: "object", ... }      ← the actual decoded schema

After:   MyEvent       = { type: "object", ... } ← decoded schema keeps its name
         MyEventStream = { type: "string", contentSchema: { $ref: "#/components/schemas/MyEvent" } }

This inverts the names for OpenAPI codegen consumers: generated clients end up with MyEvent = string and the real type renamed to MyEvent1, breaking typed access to event payloads.

Fix

StreamSse now annotates the JSON-string transport wrapper with its own ${identifier}Stream name (when the data schema has an identifier), leaving the data schema's identifier intact. This matches how identifiers are resolved/assigned elsewhere in the OpenAPI generator (SchemaAST.resolveIdentifier).

The fix is scoped to the StreamSse constructor. Other fromJsonString usages (encoding/Sse, HttpApiClient, HttpApiBuilder) are runtime decode/encode codecs that are never rendered into an OpenAPI document, so they don't share the collision.

Validation

  • pnpm lint-fix
  • pnpm test packages/effect/test/unstable/httpapi/OpenApi.test.ts (added a regression test)
  • pnpm check:tsgo

A changeset is included.

Closes #2496

HttpApiSchema.StreamSse({ data }) encodes the SSE data field as a JSON
string. That string wrapper was claiming the data schema's identifier in
the generated OpenAPI spec, pushing the decoded schema to a suffixed name
(e.g. the string wrapper became MyEvent while the object became MyEvent1).
The wrapper now takes its own ${identifier}Stream name.
@changeset-bot

changeset-bot Bot commented Jun 28, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: e8cc112

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 27 packages
Name Type
effect Patch
@effect/opentelemetry Patch
@effect/platform-browser Patch
@effect/platform-bun Patch
@effect/platform-node-shared Patch
@effect/platform-node Patch
@effect/vitest Patch
@effect/ai-anthropic Patch
@effect/ai-openai-compat Patch
@effect/ai-openai Patch
@effect/ai-openrouter Patch
@effect/atom-react Patch
@effect/atom-solid Patch
@effect/atom-vue Patch
@effect/sql-clickhouse Patch
@effect/sql-d1 Patch
@effect/sql-libsql Patch
@effect/sql-mssql Patch
@effect/sql-mysql2 Patch
@effect/sql-pg Patch
@effect/sql-pglite Patch
@effect/sql-sqlite-bun Patch
@effect/sql-sqlite-do Patch
@effect/sql-sqlite-node Patch
@effect/sql-sqlite-react-native Patch
@effect/sql-sqlite-wasm Patch
@effect/openapi-generator Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

}

const sseDataJsonSchema = (data: Schema.Constraint) => {
const json = Schema.fromJsonString(data)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Potentially the real issue is with Schema.fromJsonString transforming the schema but keeping the identifier.

I'll wait for @gcanti to weight in here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Potentially the real issue is with Schema.fromJsonString transforming the schema but keeping the identifier.

Agreed, we could add a synthetic identifier to the encoded side: #2512

@gcanti gcanti closed this in 00652fe Jul 1, 2026
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.

HttpApiSchema.StreamSse({ data }) steals the data schema's OpenAPI identifier

3 participants