{"record":{"id":"120c6640befec542","repo":"Hmbown/CodeWhale","slug":"patch-on-stdin-exceeds-the-16-mib-limit","errorCode":null,"errorMessage":"patch on stdin exceeds the 16 MiB limit","messagePattern":"patch on stdin exceeds the 16 MiB limit","errorType":"error_code","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/lib.rs","lineNumber":9945,"sourceCode":"    println!(\"Applied patch successfully.\");\n    Ok(())\n}\n\n/// Maximum bytes read for a patch on stdin. Generous for large diffs;\n/// anything larger is not a patch.\nconst MAX_STDIN_PATCH_BYTES: u64 = 16 * 1024 * 1024;\n\nfn read_patch_from_stdin() -> Result<String> {\n    let stdin = io::stdin();\n    if stdin.is_terminal() {\n        bail!(\"No patch file provided and stdin is empty.\");\n    }\n    let mut buffer = String::new();\n    stdin\n        .take(MAX_STDIN_PATCH_BYTES + 1)\n        .read_to_string(&mut buffer)?;\n    if buffer.len() as u64 > MAX_STDIN_PATCH_BYTES {\n        bail!(\"patch on stdin exceeds the 16 MiB limit\");\n    }\n    Ok(buffer)\n}\n\nasync fn run_mcp_command(\n    config: &Config,\n    workspace: &Path,\n    command: McpCommand,\n    plugins: &crate::plugins::PluginRegistry,\n) -> Result<()> {\n    let config_path = config.mcp_config_path();\n    let network_policy = config.network.clone().map(|network| {\n        crate::network_policy::NetworkPolicyDecider::with_default_audit(network.into_runtime())\n    });\n    match command {\n        McpCommand::Init { force } => {\n            let status = init_mcp_config(&config_path, force)?;\n            match status {","sourceCodeStart":9927,"sourceCodeEnd":9963,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/lib.rs#L9927-L9963","documentation":"When reading a patch from stdin, the code caps input at 16 MiB (MAX_STDIN_PATCH_BYTES). It reads LIMIT+1 bytes via `take` and bails if the buffer exceeds the limit, preventing unbounded memory use from an oversized piped input.","triggerScenarios":"Piping more than 16 MiB of patch data into the apply command's stdin — e.g. a diff containing large generated assets, lockfiles, or binary blobs rendered as text.","commonSituations":"Diffing vendored dependencies or snapshot fixtures; an accidental `git diff --no-text` on binaries; CI jobs piping whole-branch mega-diffs.","solutions":["Narrow the diff before piping (exclude vendored/generated paths: `git diff -- . ':!vendor'`)","Split the patch into chunks under 16 MiB and apply sequentially","Apply the oversized patch directly with `git apply p.diff` from a file, bypassing the stdin path"],"exampleFix":"// before\ngit diff HEAD~5 | codewhale apply   # 20 MiB diff\n// after\ngit diff HEAD~5 -- . ':!vendor' | codewhale apply","handlingStrategy":"validation","validationCode":"let size = patch_data.len();\nif size > 16 * 1024 * 1024 { /* split or narrow the diff before piping */ }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Exclude vendored/generated paths from diffs before piping","Check diff size (`git diff | wc -c`) before the apply command","Write oversized patches to a file and apply with git directly"],"tags":["cli","patch","stdin","limit"],"backgroundTag":"file-size-limit-exceeded","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}