Skip to content

fix(schema): encode output format values read back from storage - #40172

Closed
JaviOverflow wants to merge 1 commit into
anomalyco:devfrom
JaviOverflow:fix/output-format-encode
Closed

fix(schema): encode output format values read back from storage#40172
JaviOverflow wants to merge 1 commit into
anomalyco:devfrom
JaviOverflow:fix/output-format-encode

Conversation

@JaviOverflow

Copy link
Copy Markdown

Fixes #40169.

OutputFormatText / OutputFormatJsonSchema were Schema.Class, which only encodes an actual class instance. Messages come back out of storage as plain JSON, so every path that re-emits a stored message carrying format failed:

  • GET /session/:id/message returns 400 Expected OutputFormatJsonSchema, got {...} at [0]["info"]["format"] for any session where a prompt used an output format. The route encodes stored rows against Schema.Array(SessionV1.WithParts).
  • session/fork copies no messages: it re-publishes each copied message through updateMessage -> events.publish(MessageUpdated), which hits the same encode. The forked session is created but stays empty, and because the request never completes, a client that retries on timeout/5xx keeps creating empty sessions.

Making both plain structs (keeping their identifier annotations) lets the stored value encode, while leaving the wire format, the OpenAPI component names and the decode behaviour - including the retryCount default - unchanged. Nothing constructs these classes (no new, no instanceof); they are only re-exported as values from packages/core/src/v1/session.ts.

Tests

Three cases added to packages/opencode/test/session/structured-output.test.ts: encoding a stored text format, a stored json_schema format, and a stored user message carrying one. On dev they fail with the production error; with the fix they pass.

Verification

  • bun test test/session in packages/opencode: 372 pass, 0 fail
  • bun turbo typecheck: 30/30 successful
  • prettier and oxlint clean on the changed files (oxlint warning count unchanged from dev)
  • bun dev generate + packages/sdk/js/script/build.ts: the only regeneration diff is the removal of the orphan OutputFormat1 component and its generated type, which the class-based union duplicated and which nothing referenced. That is the one API-visible consequence, in case you would rather keep the symbol around.

The two public event manifest failures in packages/schema reproduce identically on a clean dev checkout and are unrelated to this change.

OutputFormatText and OutputFormatJsonSchema were Schema.Class, which only
encodes an actual class instance. Messages come back out of storage as plain
JSON, so every path that re-emits a stored message with a format field failed:

- GET /session/:id/message returned 400 BadRequest
  ("Expected OutputFormatJsonSchema, got {...} at [0]["info"]["format"]")
  for any session where a prompt used an output format.
- session/fork copied no messages, because it re-publishes each copied message
  through updateMessage -> events.publish(MessageUpdated), hitting the same
  encode. The forked session was created but left empty.

Making both plain structs keeps the wire format, the OpenAPI component names
and the decode behaviour (including the retryCount default) identical, while
allowing the stored value to encode. Regenerating drops the orphan
OutputFormat1 component, which the class-based union duplicated and nothing
referenced.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

This PR doesn't fully meet our contributing guidelines and PR template.

What needs to be fixed:

  • PR description is missing required template sections. Please use the PR template.

Please edit this PR description to address the above within 2 hours, or it will be automatically closed.

If you believe this was flagged incorrectly, please let a maintainer know.

@github-actions github-actions Bot added the needs:compliance This means the issue will auto-close after 2 hours. label Aug 2, 2026
@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

Potential Duplicate Found

PR #37541: fix(session): encode persisted output formats

Why it's related:

  • Both PRs address encoding issues with output format values (OutputFormatText/OutputFormatJsonSchema) that are persisted in storage
  • Both deal with the problem of stored values coming back as plain JSON and failing to encode properly
  • Both appear to target the same core issue of Schema encoding for output formats

Note: PR #37541 was created earlier than the current PR #40172. This could indicate:

  1. The earlier PR may have been incomplete or reverted
  2. The current PR might be a re-implementation of the same fix
  3. They could be related iterations on the same issue (issue session/fork and GET /session/:id/message fail for sessions containing a message with an output format #40169)

You may want to review PR #37541 to understand what was previously attempted and ensure the current approach doesn't duplicate prior work.

@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

This pull request has been automatically closed because it was not updated to meet our contributing guidelines within the 2-hour window.

Feel free to open a new pull request that follows our guidelines.

@github-actions github-actions Bot removed the needs:compliance This means the issue will auto-close after 2 hours. label Aug 2, 2026
@github-actions github-actions Bot closed this Aug 2, 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.

session/fork and GET /session/:id/message fail for sessions containing a message with an output format

1 participant