Skip to content

fix: block sends whose text and attachments exceed the per-message limit - #276

Merged
TheDarkPhantom merged 1 commit into
mainfrom
fix/block-oversized-turns
Oct 9, 2026
Merged

TheDarkPhantom merged 1 commit into
mainfrom
fix/block-oversized-turns

Conversation

@TheDarkPhantom

Copy link
Copy Markdown
Owner

Problem

Each attached document passed its own 500k-character cap, but a turn merges the typed text and every document into one message capped at 600k. Nothing checked that total until ProviderSendTurnInput decoded it in ProviderService.sendTurn, after the message was already persisted. The thread kept a turn the agent never saw, plus a "Provider turn start failed" row that dumped the entire prompt.

Fix

  • Shared rule (packages/shared/src/documentContext.ts): appendDocumentContexts (the join the Normalizer already did) and turnInputTooLargeReason, so server and composer measure the same thing and say the same sentence.
  • Server (Normalizer.ts): thread.turn.start / thread.fork measure text plus document blocks before any upload is claimed and fail the dispatch with the plain reason. Nothing is persisted, and pending uploads stay for a retry.
  • Headroom (contracts/provider.ts): the late provider check now allows the referenced-thread context (≤100k) and style directive (≤2k) on top of the 600k user budget, so a message accepted at dispatch cannot fail there.
  • Composer (ChatComposer.tsx): over the limit, Send (button and Enter) is disabled and a red line under the attachments explains why. Removing an attachment clears it.

Verification

  • vp test run on documentContext.test.ts, Normalizer.attachments.test.ts (new: two 350k docs rejected, nothing claimed, uploads kept), Normalizer.test.ts, parseChangelog.test.ts, and apps/web/src/components/chat: 443 passed.
  • tsgo --noEmit for contracts, shared, server, web; vp lint clean on touched files.
  • Integrated pass in the dev desktop renderer: two 350k text files show "This message and its attachments come to 700,966 characters; the limit is 600,000…", Send disabled, Enter does nothing; removing one clears the note and re-enables Send.

Claude Opus 5.5 (1M context) in Claude Code

🤖 Generated with Claude Code

Each document passed its own 500k cap, but the turn merges text and every
document into one message capped at 600k, and nothing checked that total
until the provider send. By then the message was already in the thread, so
the thread kept a turn the agent never saw plus an error dumping the prompt.

The composer now disables Send and shows a plain reason while the total is
over the limit, and the server refuses the dispatch before claiming any
upload or persisting anything. The late provider check gains headroom for
referenced-thread context and the style directive, so a message accepted at
dispatch cannot fail there.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L labels Oct 9, 2026
@TheDarkPhantom
TheDarkPhantom merged commit 8ac85f5 into main Oct 9, 2026
12 checks passed
@TheDarkPhantom
TheDarkPhantom deleted the fix/block-oversized-turns branch October 9, 2026 09:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant