{"record":{"id":"2a8b0ce1f6bbbfaa","repo":"pbakaus/impeccable","slug":"msg","errorCode":null,"errorMessage":"{msg}\n","messagePattern":"\\{msg\\}\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/skills/src/lib.rs","lineNumber":62,"sourceCode":"pub enum Flow {\n    Exit(i32),\n    Abort,\n    Throw(String),\n}\n\npub type R<T> = Result<T, Flow>;\n\n/// JS: skills.mjs#run, wrapped in cli.js's `main().catch(...)`.\npub fn run(args: &[String], io: &mut Io) -> i32 {\n    match commands::run(args, io) {\n        Ok(()) => 0,\n        Err(Flow::Exit(code)) => code,\n        Err(Flow::Abort) => {\n            io.out(\"\\nAborted.\\n\");\n            130\n        }\n        Err(Flow::Throw(msg)) => {\n            io.err(&format!(\"{msg}\\n\"));\n            1\n        }\n    }\n}\n","sourceCodeStart":44,"sourceCodeEnd":67,"githubUrl":"https://github.com/pbakaus/impeccable/blob/2bc2879276c1f321a53c4ca99d3371e411329b52/crates/skills/src/lib.rs#L44-L67","documentation":"Top-level error reporter in the skill's `run`: any command returning Flow::Throw(msg) is printed to stderr as `{msg}` and mapped to exit code 1. This is the generic terminal sink for all command errors, so the message text comes from the inner command.","triggerScenarios":"Any subcommand returns Err(Flow::Throw(msg)) from its run function; run() at crates/skills/src/lib.rs:62 formats it to stderr and returns exit code 1.","commonSituations":"Any underlying command failure (I/O, download, validation) bubbling up; wrapping `impeccable` in scripts that check exit codes; CI runs failing with exit status 1 and this stderr line.","solutions":["Read the {msg} line for the underlying cause; it is forwarded verbatim from the failing subcommand.","Fix the root cause indicated by the message (permissions, network, arguments).","In scripts, treat exit code 1 as command failure and 130 as user abort."],"exampleFix":"// before: swallowing inner error\nlet _ = cmd(io)?;\n// after: let run() print and exit 1\nreturn Err(Flow::Throw(format!(\"install failed: {e}\")));","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"const code = await run(io).catch(err => {\n  io.err(`fatal: ${err?.message ?? err}\\n`);\n  return 1; // matches Flow::Throw mapping\n});\nprocess.exitCode = code === 130 ? 130 : (code ? 1 : 0);","preventionTips":["Map Flow::Throw only for user-actionable messages; use dedicated variants for exits/aborts","In CI, assert on both stderr text and exit codes","Keep inner messages self-contained since run() prints them verbatim"],"tags":["cli","exit-code","error-reporting"],"backgroundTag":"api-error-response","analyzedSha":"2bc2879276c1f321a53c4ca99d3371e411329b52","analyzedAt":"2026-09-08T04:51:14.109Z","contentChangedAt":"2026-09-08T04:51:14.109Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}