{"record":{"id":"e9fcb20c35b721f6","repo":"jdx/mise","slug":"description-output-exceeded-bytes","errorCode":null,"errorMessage":"description output exceeded {} bytes","messagePattern":"description output exceeded (.+?) bytes","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/describe_command.rs","lineNumber":178,"sourceCode":"        }\n        if started.elapsed() >= timeout {\n            // the shell and whatever it started; the reader thread ends\n            // with the last writer of the pipe, so it is not waited for\n            active.0.kill();\n            let _ = child.kill();\n            let _ = child.wait();\n            bail!(\"took longer than {}s\", timeout.as_secs());\n        }\n        std::thread::sleep(Duration::from_millis(100));\n    };\n    // a descendant that outlived the shell and kept the pipe is not the\n    // shell's answer: the output is waited for a moment, not forever\n    let Ok(output) = receiver.recv_timeout(output_grace) else {\n        active.0.kill();\n        bail!(\"a process it started kept its output open\");\n    };\n    if output.len() > DIFF_LIMIT {\n        bail!(\"description output exceeded {} bytes\", DIFF_LIMIT);\n    }\n    if !status.success() {\n        bail!(\"exited with {status}\");\n    }\n    let Some(line) = first_line(&output) else {\n        return Ok(None);\n    };\n    annotate(\n        store,\n        entry,\n        Annotation {\n            description: Some(line.clone()),\n            description_source: Some(DescriptionSource::Command),\n            labels: None,\n            updated_at: store::now_rfc3339(),\n        },\n    )?;\n    Ok(Some(line))","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/history/describe_command.rs#L160-L196","documentation":"Thrown by `run_with_limits` when the captured description command output exceeds `DIFF_LIMIT` bytes. Description output is stored as a bounded annotation in history, so the library rejects oversized results instead of truncating them silently or bloating the store.","triggerScenarios":"A description command that emits more than DIFF_LIMIT bytes on stdout/stderr — e.g. dumping a full diff, recursive listing, or verbose logs — between the spawn and the DIFF_LIMIT check after `receiver.recv_timeout` returns.","commonSituations":"Hook scripts that print entire repository diffs, `git diff` without a stat limit, commands that echo large file contents, or verbose/debug logging accidentally enabled in a description command.","solutions":["Trim the command output: print only a summary line (e.g. `git diff --stat` instead of full diff).","Pipe output through `head -c` to cap bytes before it reaches the collector.","Quiet unrelated stderr (`2>/dev/null`) if warnings are inflating the output.","Raise DIFF_LIMIT in the describe_command configuration only if larger outputs are genuinely required."],"exampleFix":"// before\ngit diff\n// after\ngit diff --stat | head -c 4000","handlingStrategy":"validation","validationCode":"// out=$(my-command | head -c 4000); [ \"${#out}\" -le 4000 ] || echo \"too large\"","typeGuard":null,"tryCatchPattern":"// if let Err(e) = run_with_limits(...) {\n//     if e.message().starts_with(\"description output exceeded\") {\n//         // fall back to a summarizing command\n//     }\n// }","preventionTips":["Print only summary lines from description commands.","Pipe long output through `head -c` or `--stat` style flags.","Disable verbose logging in hook scripts."],"tags":["output-limit","size-limit","process"],"backgroundTag":"file-size-limit-exceeded","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}