You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Mentioning/Opening large xlsx file crashes session #50336
Same root cause as #45558: the Prompt.Base64 pattern check in packages/schema/src/prompt.ts uses a (?:X{4})* regex that fails on multi-MB strings (silently returns false under Bun/JSC, the runtime the shipped binary embeds; throws RangeError under V8). materializeAttachment runs it on the base64 of any @-mentioned file up to 20 MB, which is why a 12 MB xlsx crashes the prompt while small files work. Analysis, repro, and a parity-safe replacement in #45558 — a PR referencing both issues is on the way.
Thanks for the report — I hit the same crash and while narrowing it down I think I found the missing piece. It does not seem to be specific to xlsx, and it is not really about the attachment size either: the Prompt.Base64 schema pattern itself silently fails on long strings.
I can reproduce it without OpenCode at all, just Bun 1.4.0 and a regex test on base64 that Buffer produced (so the input is valid base64 by construction — it round-trips through Buffer.from(b64, "base64") without loss):
Bisecting the length (in steps of 4) gives 8 257 528 as the longest passing string and 8 257 532 as the shortest failing one — suspiciously close to 2^23 − 2^17 = 8 257 536. The string stays valid base64 throughout; the regex just gives up. On Node 26 (V8) the same call throws RangeError: Maximum call stack size exceeded, so the pattern looks pathological on both engines — JSC fails silently, which then surfaces as the schema InvalidValue from the logs above.
This matches the OpenCode behavior exactly. Minimal repro through the API, no plugins, no first-message requirement — any message carrying the attachment does it:
opencode api post /api/session --data '{"title":"repro","location":{"directory":"/tmp/repro"}}'
opencode api post /api/session/ses_XXX/prompt \
--data '{"text":"hi","files":[{"uri":"file:///tmp/repro/big.docx","name":"big.docx"}]}'
A 6 150 000-byte file goes through, a 6 200 000-byte file returns HTTP 500 every time, so the effective limit is ~6.19 MB of raw bytes per binary attachment (I tried .docx and .png; text/plain files go through the Read path and are unaffected). For what it is worth, when the big attachment happens to be in the first message the TUI reports this as "Failed to set up session — UnexpectedStatus: 500", which sent me looking in completely the wrong direction at first.
I suspect the same validation is also what breaks #45558 and #51350, although those look like genuinely non-base64 input (a data: prefix and such) rather than the length limit here.
If the diagnosis looks right, a fix could be to validate with something linear instead of the quantified-group pattern, e.g. /^[A-Za-z0-9+/]*={0,2}$/ together with a separate length % 4 === 0 check — I believe the two are equivalent for the standard alphabet, and neither engine has to backtrack. A size cap would only move the cliff, since the pattern is what chokes.
Activity
darellchua2 commentedon Sep 25, 2026
Same root cause as #45558: the
Prompt.Base64pattern check inpackages/schema/src/prompt.tsuses a(?:X{4})*regex that fails on multi-MB strings (silently returnsfalseunder Bun/JSC, the runtime the shipped binary embeds; throws RangeError under V8).materializeAttachmentruns it on the base64 of any@-mentioned file up to 20 MB, which is why a 12 MB xlsx crashes the prompt while small files work. Analysis, repro, and a parity-safe replacement in #45558 — a PR referencing both issues is on the way.atsyplenkov commentedon Oct 7, 2026
Thanks for the report — I hit the same crash and while narrowing it down I think I found the missing piece. It does not seem to be specific to xlsx, and it is not really about the attachment size either: the
Prompt.Base64schema pattern itself silently fails on long strings.I can reproduce it without OpenCode at all, just Bun 1.4.0 and a regex test on base64 that
Bufferproduced (so the input is valid base64 by construction — it round-trips throughBuffer.from(b64, "base64")without loss):nb64.lengthre.test(b64)truetruefalsefalseBisecting the length (in steps of 4) gives 8 257 528 as the longest passing string and 8 257 532 as the shortest failing one — suspiciously close to 2^23 − 2^17 = 8 257 536. The string stays valid base64 throughout; the regex just gives up. On Node 26 (V8) the same call throws
RangeError: Maximum call stack size exceeded, so the pattern looks pathological on both engines — JSC fails silently, which then surfaces as the schemaInvalidValuefrom the logs above.This matches the OpenCode behavior exactly. Minimal repro through the API, no plugins, no first-message requirement — any message carrying the attachment does it:
A 6 150 000-byte file goes through, a 6 200 000-byte file returns
HTTP 500every time, so the effective limit is ~6.19 MB of raw bytes per binary attachment (I tried .docx and .png;text/plainfiles go through the Read path and are unaffected). For what it is worth, when the big attachment happens to be in the first message the TUI reports this as "Failed to set up session — UnexpectedStatus: 500", which sent me looking in completely the wrong direction at first.I suspect the same validation is also what breaks #45558 and #51350, although those look like genuinely non-base64 input (a
data:prefix and such) rather than the length limit here.If the diagnosis looks right, a fix could be to validate with something linear instead of the quantified-group pattern, e.g.
/^[A-Za-z0-9+/]*={0,2}$/together with a separatelength % 4 === 0check — I believe the two are equivalent for the standard alphabet, and neither engine has to backtrack. A size cap would only move the cliff, since the pattern is what chokes.Happy to prepare a PR if that helps.