{"record":{"id":"196379bf9b267b9c","repo":"jdx/mise","slug":"exited-with-status","errorCode":null,"errorMessage":"exited with {status}","messagePattern":"exited with (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/describe_command.rs","lineNumber":182,"sourceCode":"            // 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))\n}\n\n/// The first non-empty line, trimmed, cut at the limit.","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/history/describe_command.rs#L164-L200","documentation":"run_with_limits requires the describe command to exit successfully; a non-zero status means the description could not be produced reliably, so mise bails with 'exited with <status>'. The status string (e.g. 'exit status 1' or a signal description) is included to aid debugging.","triggerScenarios":"The configured describe command's shell exits with a non-zero code or is killed by a signal during a history describe operation.","commonSituations":"Describe scripts with bugs (unset variables under `set -e`, failing subcommands); the command depends on files or env vars missing in the execution context; the shell was OOM-killed or signaled.","solutions":["Run the describe command manually to reproduce the non-zero exit and fix the underlying failure","Make the describe script resilient: handle missing inputs and end with an explicit `exit 0` when it produced a usable (possibly empty) description","Check the reported status for signals (e.g. 'signal: killed') pointing at OOM or external kills rather than a script bug"],"exampleFix":"# before: fails when the file is missing\ndescribe.sh: cat /path/maybe-missing.txt\n\n# after\ndescribe.sh: cat /path/maybe-missing.txt 2>/dev/null || echo \"(no description)\"","handlingStrategy":"try-catch","validationCode":"describe-command >/dev/null 2>&1 && echo ok || echo \"describe command exits non-zero ($?); fix it before use\" >&2","typeGuard":null,"tryCatchPattern":"match history::describe() {\n    Err(e) if e.to_string().starts_with(\"exited with\") => {\n        // log the status; fall back to a default description or fix the command\n    }\n    r => r?,\n}","preventionTips":["Test describe scripts standalone before wiring them into history","Make scripts tolerant of missing inputs and end with explicit success","Check reported signal statuses for OOM/kill scenarios"],"tags":["history","process","exit-code"],"backgroundTag":"nonzero-exit-status","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}