Skip to content

fix(session): read text attachments as text for non-text/plain MIME types#34786

Open
adityachaudhary99 wants to merge 1 commit into
anomalyco:devfrom
adityachaudhary99:fix/text-upload-garbled-17301
Open

fix(session): read text attachments as text for non-text/plain MIME types#34786
adityachaudhary99 wants to merge 1 commit into
anomalyco:devfrom
adityachaudhary99:fix/text-upload-garbled-17301

Conversation

@adityachaudhary99

Copy link
Copy Markdown

Issue for this PR

Closes #17301

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Attaching a text file could send binary-looking garbage to the model instead of the file's contents. resolveUserPart (session/prompt.ts) only routed an attachment through the readable-text path (the Read tool) when its MIME was exactly text/plain. A file with no extension — or any unrecognized text file — resolves to application/octet-stream, so it skipped that path and hit the branch that base64-encodes the raw bytes and prepends a synthetic Called the Read tool… frame. The model then received a data-URL of raw bytes, which is the garbled output in the issue.

The earlier #26152 fixed the run --file producer (real MIME lookup), but the consumer here still only recognized literal text/plain, so the interactive/upload path stayed broken (and extension-less files arguably got worse, since they now resolve to octet-stream).

The fix gates the text path on a shared isTextMime() check (text/*, JSON/XML/JS, empty, and the application/octet-stream unknown fallback) instead of an exact string. The Read tool already content-sniffs, so real text reads cleanly, sniffed images/PDFs still become proper attachments, and genuine binary now fails closed with an honest message instead of a garbled blob. Image/PDF MIMEs are untouched.

How did you verify your code works?

Added two cases to test/session/prompt.test.ts: a text file attached as application/octet-stream (the exact repro — an extension-less file) and as text/markdown both produce a clean synthetic text part containing the file's text, with zero forwarded binary parts. I couldn't run the full suite in my isolated worktree (the @opencode-ai/core workspace alias resolves to a stale checkout there), so I rely on CI for the suite.

Screenshots / recordings

N/A — not a UI change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

…ypes

resolveUserPart only routed a file attachment through the readable-text (Read
tool) path when its MIME was exactly "text/plain". An extension-less or
unrecognized text file resolves to application/octet-stream, so it fell through
to the branch that base64-encodes the raw bytes and prepends a synthetic Read
tool-call frame — the model then received binary garbage (anomalyco#17301). This is the
consumer side; the earlier anomalyco#26152 only fixed the `run --file` producer.

Gate the text path on a shared isTextMime() check (text/*, json/xml/js, empty,
and the octet-stream unknown fallback) so text files are read as UTF-8, sniffed
images/PDFs still become proper attachments, and genuine binary fails closed.

Closes anomalyco#17301

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.

Text file upload produces garbled/corrupted output in conversation

1 participant