rtk-ai/rtk · error
hook stdin exceeds {} byte limit
Error message
hook stdin exceeds {} byte limit What it means
RTK's PreToolUse hook (Claude Code / VS Code Copilot CLI) reads the tool-call JSON from stdin through read_stdin_limited, capped at STDIN_CAP = 1 MiB. The reader takes CAP+1 bytes so oversize input is rejected outright (bail!) instead of truncated — a truncated hook JSON would be unparseable and could silently disable filtering.
Source
Thrown at src/hooks/hook_cmd.rs:23
use super::constants::PRE_TOOL_USE_KEY;
use super::permissions::{self, PermissionVerdict};
use anyhow::{Context, Result};
use serde_json::{json, Value};
use std::io::{self, Read, Write};
use crate::discover::registry::{has_heredoc, rewrite_command};
const STDIN_CAP: usize = 1_048_576; // 1 MiB
fn read_stdin_limited() -> Result<String> {
let mut input = String::new();
io::stdin()
.take((STDIN_CAP + 1) as u64)
.read_to_string(&mut input)
.context("Failed to read stdin")?;
if input.len() > STDIN_CAP {
anyhow::bail!("hook stdin exceeds {} byte limit", STDIN_CAP);
}
Ok(input)
}
// ── Copilot hook (VS Code + Copilot CLI) ──────────────────────
/// Format detected from the preToolUse JSON input.
enum HookFormat {
/// VS Code Copilot Chat / Claude Code: `tool_name` + `tool_input.command`, supports `updatedInput`.
/// If using the PreToolUse pascal case form, Copilot CLI also remaps its native `bash`/`powershell`
/// runtime tool to `tool_name: "Bash"` for this schema and honors its `updatedInput`, live-verified
/// on Linux+Windows 11 with Copilot CLI 1.0.73+ by rewriting a marker command end-to-end
/// see <https://github.com/rtk-ai/rtk/pull/3179#issuecomment-5088268495>.
VsCode { command: String },
/// GitHub Copilot CLI's native schema: camelCase `toolName` + `toolArgs` (JSON string),
/// supports `modifiedArgs` for transparent rewrite. `rtk init --copilot` no longer
/// registers this schema (Copilot CLI honors the PascalCase `VsCode` schema on its
/// own — registering both caused a redundant second hook invocation per tool call,View on GitHub (pinned to d977e1c316)
Solutions
- Move big payloads out of the command: write them with a file tool first, or fetch them (`curl -o /tmp/payload ...`), then reference the path in the command
- Split the work so each tool call stays well under 1 MiB of serialized JSON
- For bulky inline data, keep only an indirect reference (path, URL, or `base64 -d /tmp/x.b64`) in the command itself
Example fix
# before: heredoc pushes hook JSON past 1 MiB tee /tmp/app.conf <<'EOF' <2 MB of config...> EOF # hook stdin exceeds 1048576 byte limit # after: write the file with a file tool (no hook stdin), then just reference it # tool: write file /tmp/app.conf (payload goes through the file API) chmod 644 /tmp/app.conf && wc -c /tmp/app.conf
Defensive patterns
Strategy: validation
Validate before calling
bash: # keep the tool-call payload well under the 1 MiB hook cap before invoking the agent tool SIZE=$(wc -c < payload.json 2>/dev/null || echo 0) if [ "$SIZE" -gt 1000000 ]; then echo "payload $SIZE bytes exceeds ~1 MiB hook stdin cap — reference a path instead" >&2 exit 2 fi
Try / catch
rust (hook harness):
match read_stdin_limited() {
Err(e) if e.to_string().contains("hook stdin exceeds") => {
// input too large to inspect: allow the tool call unfiltered rather than block it
Ok(std::process::exit(0))
}
r => r,
} Prevention
- Never paste multi-hundred-KB heredocs/base64 into agent bash calls — write files with file tools and reference paths
- Budget the serialized tool_input JSON, not just the visible command: the hook sees the whole envelope
- Keep inline payloads to kilobytes; fetch or decode bulky data from disk in the command
- The 1 MiB cap (STDIN_CAP, hook_cmd.rs) is deliberate — truncation would corrupt the hook JSON
When it happens
Trigger: An agent tool call whose serialized JSON exceeds 1 MiB: a bash command embedding a giant heredoc (data file pasted inline), a base64 blob (certificates, images), or minified bundle content. The hook receives the whole tool_input envelope, so the payload — not the visible command — is what crosses the cap.
Common situations: Agents pasting whole files as heredocs instead of using file-write tools; inline base64 of binaries/certs; generated code or fixtures injected into commands; very long curl payloads with embedded JSON.
Related errors
- stdin exceeds {} byte limit
- rtk find does not support compound predicates or actions (e.
- Failed to relay stdin: {}
- Failed to read stdin: {}
- Cursor hooks are global-only. Use: rtk init -g --agent curso
AI-assisted analysis of rtk-ai/rtk@d977e1c316 (2026-08-16).
Data as JSON: /api/errors/f27562393e9202a4.
Report an issue: GitHub.