Skip to content

Terminal tool corrupts multiline commands exceeding 1024 bytes #296955

@jcansdale

Description

@jcansdale

Bug

The terminal tool (run_in_terminal) corrupts any multiline command exceeding 1024 bytes. After byte 1024, content wraps around and replays earlier buffer content, destroying the remainder of the command and leaving the shell stuck in quote> or heredoc> mode.

Minimal Reproduction

Ask Copilot to run this in the terminal (19 lines × 55 chars + wrapper = 1077 bytes):

echo 'L01 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
L02 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
L03 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
L04 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
L05 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
L06 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
L07 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
L08 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
L09 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
L10 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
L11 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
L12 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
L13 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
L14 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
L15 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
L16 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
L17 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
L18 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
L19 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' | wc -c

Expected: Outputs 1064
Actual: L19 becomes garbled (L19 aaaaaL02 aaa...), closing ' is lost, shell stuck at quote>

Reduce to 18 lines (1021 bytes) → works perfectly. The boundary is exactly 1024 bytes.

Verified Facts

Test case Result
18 lines × 55 chars (1021 bytes), multiline ✅ Works
19 lines × 55 chars (1077 bytes), multiline ❌ Corrupts at byte 1024
Same 20-line content via $'...\n...' (1156 bytes, single-line) ✅ Works
Single line of 2000+ chars ✅ Works
cat << 'EOF' heredoc > 1024 bytes ❌ Corrupts at byte 1024
python3 -c "..." multiline > 1024 bytes ❌ Corrupts at byte 1024

The corruption only affects multiline commands (containing literal newline characters) and always occurs at exactly byte 1024.

Why This Is a Serious Problem

The failure mode is cascading and difficult to recover from:

  1. Silent corruption: The tool reports success ("The tool simplified the command to...") but the shell receives garbled data. The agent has no way to detect this before it happens.

  2. Shell gets permanently stuck: The closing delimiter (', ", EOF) is lost in the corruption, so the shell enters quote> or heredoc> mode. Every subsequent command the agent sends is swallowed as continuation of the broken quote — the terminal is bricked until a new one is opened.

  3. Extremely common trigger: 1024 bytes is a very low threshold. Any of these routine operations can exceed it:

    • gh issue create --body '...' or gh pr create --body '...' with a detailed description
    • Heredoc writes (cat > file << 'EOF')
    • Inline Python/Node scripts (python3 -c "...")
    • Any multiline shell script pasted to the terminal
  4. Hard to diagnose: The garbled output looks like random gibberish — fragments of earlier content mixed with later content. Without knowing about the 1024-byte boundary, this appears to be a non-deterministic, unreproducible glitch. (We initially filed and closed a report as "unreproducible" before discovering the byte-count trigger.)

  5. Recovery makes things worse: When the agent sees an error or stuck shell, it typically retries. But the terminal is stuck in quote mode, so retries just feed more text into the broken quote, creating increasingly bizarre output and wasting tokens.

Root Cause Hypothesis

The terminal tool uses a different input mechanism for multiline commands (likely bracketed paste or line-by-line writing to the PTY) compared to single-line commands. This multiline path appears to use a 1024-byte buffer — a classic PIPE_BUF or PTY canonical-mode buffer size — that wraps on overflow rather than flushing and continuing.

Environment

  • VS Code Insiders
  • macOS
  • zsh
  • Copilot agent mode (Claude)

Metadata

Metadata

Labels

bugIssue identified by VS Code Team member as probable bugchat-terminalThe run in terminal tool in chatimportantIssue identified as high-priorityinsiders-releasedPatch has been released in VS Code Insiders

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions