{"record":{"id":"578b1253a1233c7f","repo":"jdx/mise","slug":"hook-command-failed-status","errorCode":null,"errorMessage":"hook command failed: {status}","messagePattern":"hook command failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/hooks.rs","lineNumber":781,"sourceCode":"            let mut c = std::process::Command::new(&shell[0]);\n            for a in &cmd_args {\n                c.raw_arg(a);\n            }\n            c.env_clear();\n            c.envs(env.iter());\n            if matches!(hook.hook, Hooks::Preinstall | Hooks::Postinstall) {\n                c.current_dir(project_root);\n            }\n            // Send the hook's stdout to mise's stderr (matching the duct\n            // `stdout_to_stderr()` the non-cmd path uses) by handing the child a\n            // clone of our stderr handle. Redirecting the descriptor directly —\n            // rather than piping through a reader thread — means a hook that\n            // spawns a background child holding the write end can't block us\n            // waiting for pipe EOF, and stdout/stderr ordering is preserved.\n            c.stdout(std::io::stderr().as_handle().try_clone_to_owned()?);\n            let status = c.status()?;\n            if !status.success() {\n                eyre::bail!(\"hook command failed: {status}\");\n            }\n            return Ok(());\n        }\n    }\n\n    let cwd = matches!(hook.hook, Hooks::Preinstall | Hooks::Postinstall).then_some(project_root);\n    let mut command = cmd(&shell[0], args).full_env(&env);\n    if let Some(cwd) = cwd {\n        command = command.dir(cwd);\n    }\n    crate::inline_command::optimize_expression(command, run, &env, cwd, direct_enabled)\n        .stdout_to_stderr()\n        .run()?;\n    Ok(())\n}\n\nasync fn execute_task(\n    config: &Arc<Config>,","sourceCodeStart":763,"sourceCodeEnd":799,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/hooks.rs#L763-L799","documentation":"When executing a hook command (src/hooks.rs), mise runs the command synchronously and checks its exit status. If the hook's process exits non-zero, execution bails with 'hook command failed: {status}' reporting the exit code/signal.","triggerScenarios":"Any hook (e.g. preinstall/postinstall or configured hooks) whose shell command exits with a non-zero status during run_matched_hook's execution path.","commonSituations":"A postinstall script referencing a missing tool or bad path; a preinstall gate script intentionally failing to block an install; script bugs (syntax error, failed assertion) in hook commands; environment differences making a hook fail under mise but not in an interactive shell.","solutions":["Read the hook's own stderr/stdout just above the error — the hook's output explains the root cause; fix the hook script.","Run the hook's command manually in the project root to reproduce and debug it outside mise.","If the hook intentionally blocks (preinstall gate), resolve the condition it checks (e.g. required config, allowed versions) before retrying."],"exampleFix":"// before (.mise.toml hook)\n[hooks.postinstall]\nrun = \"npm run setup --silent\"   # fails if 'setup' script missing\n// after\n[hooks.postinstall]\nrun = \"npm run setup --if-present --silent\"","handlingStrategy":"try-catch","validationCode":"command -v \"$hook_cmd\" >/dev/null 2>&1 && echo ok || echo \"hook command not available\"","typeGuard":null,"tryCatchPattern":"if ! mise install; then\n  echo \"install failed at hook stage; inspect hook output above\"\n  mise cfg ls 2>/dev/null || cat mise.toml\nfi","preventionTips":["Test hook commands manually in the project root before committing them","Use --if-present style guards in package-manager scripts invoked by hooks","Keep hooks idempotent and fail with clear messages"],"tags":["hooks","subprocess","exit-code"],"backgroundTag":"command-not-found","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"}