Skip to content

session: multi-MB inline attachment makes a session permanently fail to decode #55110

Closed as duplicate

Description

@ljx-lll

Description

opencode-issue-body.md

Plugins

No response

OpenCode version

v2.0.28

Steps to reproduce

Prerequisites: opencode v2.0.28, no plugins/MCP configured. Reproduced on Windows 11.

  1. Open any session and attach a file large enough that its base64 encoding exceeds ~5,000,000 characters (roughly a 4 MB or larger binary file; e.g. a PDF or zip). Smaller attachments (up to ~500 KB base64) do NOT trigger the bug.
  2. Send the message so the attachment is stored inline (files[0].source.type === "inline").
  3. Trigger a session reload: restart the background service (opencode service restart), or reopen the session, or call GET /api/session/{sessionID}/context.

Expected: the session loads normally and returns its history including the attachment.
Actual: the session can never be loaded again. Every load and every server start reports the same message id:

level=ERROR message="Failed to drain Session"
cause="Session.MessageDecodeError: Failed to decode message msg_... in session ses_..."

and GET /api/session/{sessionID}/context returns HTTP 500:

{"_tag":"UnknownError","message":"Unexpected server error. Check server logs for details.","ref":"err_..."}

Deterministic minimal reproduction of the root cause (Node/V8, same engine as Bun):

const re = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/u;
re.test("A".repeat(5_000_000));
// RangeError: Maximum call stack size exceeded

Screenshot and/or share link

No response

Operating System

windows11

Terminal

windows

Activity

  1. opencode-agent commented on Oct 13, 2026

    @opencode-agent
    Contributor

    Thanks for the detailed report and the minimal regex reproduction, they point straight at the cause. I think this is a duplicate of #45558.

    The Prompt.Base64 check in packages/schema/src/prompt.ts uses the exact regex you quoted. On strings longer than a few MB it either overflows the stack (V8) or silently returns false (Bun/JSC). In #45558 this shows up as a 500 on POST /prompt. Here the attachment was stored first, so the same check now fails each time the message is decoded on reload (Session.MessageDecodeError). The stored data is valid base64, so fixing the regex should make these sessions load again.

    Possible duplicates and related issues, ordered from most to least likely:

    The bot will close this issue as a duplicate in 1 day unless you reply explaining how your problem is different.

  2. ljx-lll commented on Oct 13, 2026

    @ljx-lll
    Author

    Thanks -agreed on the root cause: the backtracking Prompt.Base64 regex in packages/schema/src/prompt.ts. I'm not claiming a different cause, and the fix in #51272 should resolve it.

    The reason I filed separately is that the impact is a distinct and more severe failure mode than the attach-time 500 in #45558:

    • In attachments: dragging file or pasting file path into input fails session setup (Prompt.Base64 500 on /prompt) #45558 the regex failure happens synchronously while handling POST /prompt, so the message is never stored and the user can just retry.
    • Here the attachment is stored successfully first. The same check then runs on every decode of the persisted message (SessionHistory.load), so the session becomes permanently unloadable: Session.MessageDecodeError on every drain / server start, and HTTP 500 on GET /api/session/{sessionID}/context. There is no in-app recovery or repair path, so the user loses access to the entire session history, not just the single message.

    Two requests:

    1. Please make sure the fix recovers sessions that already have a large inline attachment persisted. Since the stored data is valid base64, the corrected check should make them load again 鈥?a test that reloads such a stored session would be valuable, because that reload path is what actually bricks the history (the /prompt path does not).
    2. If possible, keep this tracked or link it from attachments: dragging file or pasting file path into input fails session setup (Prompt.Base64 500 on /prompt) #45558 so the persisted-session reload impact is explicitly covered by tests.

    I'm fine with it being closed as a duplicate if you consider the impact covered 鈥?I mainly want to flag that the decode/reload path is what breaks existing sessions, and that it currently has no recovery story for affected users.

  3. opencode-agent commented on Oct 13, 2026

    @opencode-agent
    Contributor

    Thanks, and you're right that the impact here is worse. In #45558 the request fails when you send the prompt, so you can just retry. Here the message is saved first, and then the whole session can't be loaded until the check is fixed.

    On your two points:

    1. Existing sessions: the same Prompt.Base64 schema is used both when a prompt is sent and when a saved message is read back during a session load. The stored data is valid base64, so once the regex is replaced, these sessions should load again without any repair step. The fix is fix(schema): validate canonical base64 without a backtracking regex #51272, which is open and not merged yet. Its tests check the schema directly, including a 20 MB value, which is the same check the reload runs. There is no test yet that reloads a saved session with a large attachment. Whether to add one is up to the maintainers, so it's worth asking for it on fix(schema): validate canonical base64 without a backtracking regex #51272 or attachments: dragging file or pasting file path into input fails session setup (Prompt.Base64 500 on /prompt) #45558.
    2. Tracking: this issue stays linked from attachments: dragging file or pasting file path into input fails session setup (Prompt.Base64 500 on /prompt) #45558 after it is closed, so your write-up about sessions that no longer load stays easy to find. Please also leave a short comment on attachments: dragging file or pasting file path into input fails session setup (Prompt.Base64 500 on /prompt) #45558 pointing here, so that impact is discussed alongside the fix.

    Until the fix ships there's unfortunately no way to recover an affected session from inside the app. To avoid hitting this again in the meantime, don't attach files over ~4 MB (for example, convert PDFs to text first).

    Since the cause and the fix are the same, this will still be closed as a duplicate of #45558.

  4. opencode-agent commented on Oct 14, 2026

    @opencode-agent
    Contributor

    Closing this as a duplicate of #45558, since it has the same root cause: the Prompt.Base64 regex fails on multi-MB base64. Thanks for confirming that, and for the clear write-up on how a stored large attachment stops the whole session from loading.

    The fix is #51272, which is still open. Once a fix like that ships, sessions that already fail to load should open again, because the stored data is valid base64. If you'd like a test that reloads a saved session with a large attachment, please ask on #45558 or #51272, where the maintainers are discussing the fix. If you still see the problem after the fix is released, please open a new issue and link this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions