Repository navigation
Description
Summary
After updating to v0.0.0-beta-18387, dragging a file into the TUI input box, or copying a file path and pasting it into the input, causes the session to fail to start. The server returns HTTP 500 on POST /api/session/<id>/prompt because the file is treated as an image attachment and its base64 payload fails the Prompt.Base64 schema validation. Result is surfaced to the user as "Failed to set up session".
Environment
- opencode version: v0.0.0-beta-18387
- OS: Windows 10.0.26200.9168 (win32 x64)
- Terminal: TERM=xterm-256color (launched via Git bash)
- Shell: COMSPEC=C:\WINDOWS\system32\cmd.exe (opencode config
shell: "bash") - Install/channel: beta
- Active plugins: none found in config
Reproduction
- Launch the TUI with
opencode2(no config/images involved — globalopencode.jsonhas no embedded base64 images, project has noopencode.json). - In the input box, either:
- drag a file (e.g. a source/text file) into the input, or
- copy a file path and paste it into the input.
- Send the message (this is typically the first prompt of the session).
- Observe "Failed to set up session" in the TUI.
Pure-text first messages work fine; only messages that contain a dragged file or a pasted file path trigger the failure.
Expected Behavior
Dragging a file or pasting a file path into the input should attach/reference the file as a file (text/context), not route it through the image-attachment base64 path. The session should set up and the message should be delivered.
Actual Behavior
The server logs a 500 with a schema validation error originating from the image-attachment normalization path:
POST /api/session/<id>/prompt http.status=500
cause: Error: Schema validation failed
at Session.normalizeImageAttachment (...)
at Session.materializeAttachment (...)
at Session.resolvePrompt (...)
at Session.prompt (...)
[cause]: expected "a string matching the RegExp ^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"
identifier: "Prompt.Base64"
The attached file content (or the pasted path data, which can include a data:image/...;base64, prefix or other non-base64 characters) does not satisfy the strict Prompt.Base64 pattern, so the prompt is rejected before the model is ever called.
Additional Context
- The failure is consistent (100% reproducible) on this version whenever the first message carries a dragged file or pasted file path.
- The same action worked before the update; this appears to be a regression in
v0.0.0-beta-18387. - Workaround: avoid drag-drop / paste-path; reference files with the
@file-reference (mention) syntax instead, which goes through the text/context channel and does not trigger image base64 validation. - The background service itself is healthy (
opencode2 service statusreturns a valid address); the failure is isolated to the prompt-with-attachment handling.
Redacted server log excerpt (username/workspace paths removed):
timestamp=... level=INFO run=de674f6b cause="Error: Schema validation failed
at Session.normalizeImageAttachment (...)
at Session.materializeAttachment (...)
at Session.resolvePrompt (...)
at Session.prompt (...)
[cause]: Error: {... "expected":"a string matching the RegExp ^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$", "identifier":"Prompt.Base64" ...}
" http.span=387 role=server http.method=POST http.url=/api/session/<id>/prompt http.status=500
Activity
github-actions commentedon Aug 27, 2026
This issue might be a duplicate of existing issues. Please check:
MilkyWay008 commentedon Aug 27, 2026
The 500 on /api/session//prompt after beta-18387 is the attachment normalizer routing non-image files through the Prompt.Base64 validator, the schema error is just it tripping on a path that was never meant to hit that regex. On Windows 10.0.26200 with git bash the pasted Windows path is the trigger, so the @-mention workaround sidesteps the whole branch, and #44310/#35697 cover the same normalizer area so the fix will probably land together. I keep a portable Hermes OTG on a USB stick as my rescue agent for exactly these update regressions, https://github.com/MilkyWay008/Hermes-OTG if you want to poke at it.
guillemus commentedon Sep 13, 2026
Still reproducing on OpenCode 2.0.3, latest channel, on macOS (Apple Silicon).
I attempted to attach an approximately 11 MB
.harfile. Submitting the prompt fails with the samePrompt.Base64validation error reported here.Relevant server log, September 13, 2026 (UTC), with the session ID redacted:
The same stack trace and HTTP 500 appear repeatedly across multiple session IDs between 14:22 and 14:24 UTC.
darellchua2 commentedon Sep 25, 2026
Root-caused this one (and #50336 — same bug) on v2.0.16.
Prompt.Base64inpackages/schema/src/prompt.tsvalidates with/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/Regex engines recurse per iteration of the
(?:…{4})*group, so past a few MB the check stops working. Under Bun 1.4.2/JSC (the runtime embedded in the shipped binary) it silently returnsfalsefor canonical base64 — that's theInvalidValueschema issue in the 500 logs fromPOST /api/session/<id>/prompt. Under V8 the same input throws RangeError instead.materializeAttachmentbase64-encodes attachments up to the 20 MB limit and runs this check on the result, so any@-attached file over roughly 5 MB (any type — PDF, xlsx, …) fails the prompt with a 500 before the provider is called. Small attachments pass, which is why images seem fine.Minimal repro:
The grouped-quantifier shape can't be fixed with a better regex. Canonical base64 is decidable with a length preflight plus a structurally linear pattern (a single char-class star compiles iteratively, no recursion):
I fuzzed 20k mutated canonical strings against both — zero mismatches (
AB==/ABC=accept,AB=/ABCD==/A===reject,""accepted, base64url-_rejected, same as the current pattern). The 27.9M-char encoding of a 20 MB file passes in 6 ms; the current pattern returnsfalseon it in 156 ms under Bun 1.4.2.Happy to send a PR if useful.
AndreyMentor commentedon Oct 5, 2026
Adding data from a second report on the current desktop release. This is the same failure mode (
Prompt.Base64validation -> HTTP 500 onPOST /api/session/<id>/prompt), but with a different surface and trigger, so it may help narrow the root cause.Still present in 2.0.11 (desktop)
~/.config/opencode/opencode.jsoncwith"model": "opencode-go/qwen3.7-plus"This is roughly six weeks after beta-18387, on a different surface (desktop app rather than TUI).
Trigger is not drag-and-drop
The report here involves pasting/attaching a screenshot in the desktop composer, not dragging a file or pasting a file path. Pure-text prompts in the same session succeed normally.
Frequency
34 failures inside a single burst,
2026-10-04T13:00:45.759Zto2026-10-04T13:09:47.871Z(~9 minutes). The cadence looks like retries: most entries repeat 0.4-0.5s apart, with 1-200s gaps between groups.CLI path works - this is the most useful clue
Attaching the same kind of file through the CLI succeeds, on both installed versions:
So
--fileproduces aPrompt.Base64-valid payload while the desktop composer does not. That points at the desktop client's encoding/normalization step rather than the server-side schema itself. Possible differences worth checking on the desktop path: adata:image/...;base64,prefix being left in place, whitespace or newlines surviving from clipboard encoding, or a base64url alphabet without padding.User-visible symptom
The prompt is dropped silently, the session stays in
running, and the composer shows only "Queue" for every subsequent message. From the outside the agent looks like it hung or stopped mid-task, with nothing in the UI to explain why.Diagnostics note
This failure is logged as
level=INFOwithcause=rather thanlevel=ERROR, so it does not show up in a normal error search of the log. Searching forSchema validation failedwas the only way to find it.Possibly related
#35112 reports image inputs on
qwen3.7-plusvia OpenCode Go being rejected upstream by a 6 MB request body limit. That is a different failure (provider-sideBadRequest.TooLarge, not a server-side 500), but large screenshots on the Go provider may hit both.rojosinalma commentedon Oct 6, 2026
Still reproduces on 2.0.22 (Linux x86-64,
opencode serve, prompt sent by a web client as adata:application/pdf;base64,…URI). A 7 MB PDF failsPOST /api/session/<id>/promptwith HTTP 500 and the sameSchema validation failed … Prompt.Base64 … InvalidValuecause fromSessionPrompt.normalizeImageAttachment; a small PDF, a small PNG and a 1.8 MB PNG (which does get resized to JPEG) all go through.Isolated the threshold in the runtime the binary embeds (Bun 1.4.2 / JSC): the
Prompt.Base64regex returnsfalsefor canonical, padded base64 as soon as the string is longer than ~8.25 M chars, i.e. an attachment of roughly 5.9 MB or more. Below that it istrue, above itfalse, independent of content (repeating bytes and random bytes behave the same), and it never throws:So every attachment between ~5.9 MB and the 20 MB limit that
materializeAttachmentenforces is rejected as a 500, regardless of transport (@mention, drag and drop, or adata:URI from an API client). #51272 replaces the regex with a decode-based check and would fix this; theneeds:issuelabel on it looks like the bot artefact mentioned there, since this issue and #50336 are linked in its body.Skeptomenos commentedon Oct 15, 2026
Still reproducible on 2.0.29 (
042d083), Linux arm64, no plugins, directly againstopencode servewith a local synthetic model.In a fresh session, POST this input to
/api/session/<id>/prompt:It returns HTTP 500 with zero response bytes. With 4,000,000 bytes it returns 200. Two 4,000,000-byte files in one prompt also return 200 and reach the local model intact, despite the larger request body. Plain
data:text and PDF-signature bytes reproduce it too.On this binary, 5,345,276 decoded bytes pass and 5,345,277 fail. This is an observed runtime boundary, not a portable size limit. Exactly 20 MiB returns the empty 500; 20 MiB plus one byte returns the intended JSON 400.
The on-disk server log identifies
SessionPrompt.normalizeImageAttachmentandPrompt.Base64. The same valid base64 makes the pinned validator return false in Bun/JSC. This supports the existing diagnosis and #51272. Expected: attachments within the declared 20 MiB limit pass admission.geverl commentedon Oct 22, 2026
Following the suggestion from the bot on #58042 (whose report I filed as a duplicate of this one) — two UX points, plus some measurements that may be useful as regression-test material for #51272.
UX points
1. Enforce the limit at attach/upload time. The code intends to allow 20 MB, but the regex fails at ~5.3 MB of raw file data, so users hit a wall well before the documented limit. Failing at attach time with a clear message ("this file is too large to attach") is much easier to act on than a session that silently becomes unreadable days later.
2. Report decode failures per attachment / per message. Today a single oversized attachment makes
GET /api/session/{id}/messagereturn 500 for the whole session, and the Desktop app shows onlyUnknownError: Unexpected server error. Check server logs for details.Every message in that session becomes unreachable, including the ones that are perfectly valid. Reporting which attachment failed would at least make the problem diagnosable from the UI.Measurements for the fix
Bisected against a running 2.1.2 server. One attachment per message, valid base64, everything else in the message valid:
datalengthThe limit is per attachment, not per message and not per response:
Two things I'd suggest checking when the replacement lands:
For context on impact: in one of my sessions this made three ~7.3 MB PDFs unreadable, and the failure took the entire session history with it — the three sessions I had to recover were recovered by rebuilding the v2 rows from the legacy v1
message/parttables, which are still present inopencode.dbafter the migration.neriousy commentedon Oct 23, 2026
Preserving measurements from #58116: a valid file attachment around 3.2 MB triggers the Base64 validation
RangeError/HTTP 500 path. The reporter also suggests rejecting unsupported binaries before Base64 materialization to avoid the expensive validation path.opencodejr commentedon Oct 28, 2026
Thanks for the report, and to everyone who added logs here.
I reproduced this on 2.1.4. In the TUI I attached a ~6.8 MB text file to the first prompt (as an
@mention, which reaches the same server-side attachment code as a dragged or pasted path) and sent it. It failed with "Failed to set up session — UnexpectedStatus: 500", the samePrompt.Base64failure. The cause is the old base64 check: on Bun its regex starts rejecting valid base64 once an attachment reaches about 6 MB. A 4.4 MB file sent the same way went through.On the latest
dev(a882cf9) the same steps work: the file is attached and the message is delivered. The fix is #58811, which replaced the regex with a check that runs in linear time. It should also be in v2.2.0, though I only testeddev. So this is most likely fixed and should reach you with the next update.I could only reproduce this with files over about 6 MB. If you still see it after updating, especially with a small file or a pasted Windows path from Git Bash, please reply with your version, the file size and the server log line.
The bot will close this issue in 1 day unless you reply that it still happens.
geverl commentedon Oct 28, 2026
Confirmed fixed on 2.2.0 — including one case the reproduction above doesn't cover.
Everything reported so far is the write path (
POST /api/session/:id/prompt). The samePrompt.Base64also gates decoding of already-stored messages, which is how it presents as a 500 onGET /api/session/:id/message: a single oversized attachment makes the entire session unreadable, including every valid message in it.Test
A v1-era database with one session containing three
application/pdfattachments stored inline at 9,756,528 / 9,788,748 / 9,824,192 base64 characters (~7.3 MB each). They were written by 1.18.32, before any of this validation existed, so the bytes were never re-encoded or re-uploaded. The same database file, unmodified, served by two runtimes:GET /api/session/:id/messageThe 2.2.0 response returns all 23 messages of that session with all three PDFs intact.
What this means
For the record, #58042 (closed as a duplicate of this) was specifically this read-path variant, and #51272 was the earlier attempt at the same fix; #58811 supersedes it.
opencodejr commentedon Oct 29, 2026
Closing this as completed, since nobody has replied in the past day to say it still happens.
To recap: the
Prompt.Base64HTTP 500 ("Failed to set up session") reproduced on 2.1.4 with a ~6.8 MB attachment. On the latestdev(a882cf9) the same steps work, thanks to the linear-time base64 check from #58811. The fix should reach you in the next release you update to.If you still see this on a newer version, please comment here or open a new issue. It would help to include your version, the attachment's size and type, how you attached it, and the server log line.