{"record":{"id":"d13d75f545f60536","repo":"Hmbown/CodeWhale","slug":"command-timed-out-after-ms","errorCode":null,"errorMessage":"Command timed out after {}ms","messagePattern":"Command timed out after (.+?)ms","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/lib.rs","lineNumber":9133,"sourceCode":"            print!(\"{}\", String::from_utf8_lossy(&stdout));\n        }\n        if !stderr.is_empty() {\n            eprint!(\"{stderr_str}\");\n        }\n        if sandbox_denied {\n            eprintln!(\n                \"{}\",\n                SandboxManager::denial_message(sandbox_type, &stderr_str)\n            );\n        }\n\n        if !status.success() {\n            bail!(\"Command failed with exit code {exit_code}\");\n        }\n    } else {\n        let _ = child.kill();\n        let _ = child.wait();\n        bail!(\"Command timed out after {}ms\", timeout.as_millis());\n    }\n    Ok(())\n}\n\nfn parse_sandbox_policy(\n    policy: &str,\n    network: bool,\n    writable_root: Vec<PathBuf>,\n    exclude_tmpdir: bool,\n    exclude_slash_tmp: bool,\n) -> Result<crate::sandbox::SandboxPolicy> {\n    use crate::sandbox::SandboxPolicy;\n\n    match policy {\n        \"danger-full-access\" => Ok(SandboxPolicy::DangerFullAccess),\n        \"read-only\" => Ok(SandboxPolicy::ReadOnly),\n        \"external-sandbox\" => Ok(SandboxPolicy::ExternalSandbox {\n            network_access: network,","sourceCodeStart":9115,"sourceCodeEnd":9151,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/lib.rs#L9115-L9151","documentation":"When the exec child outlives its timeout budget, the runner kills it (kill + wait) and bails with the elapsed limit in milliseconds. Output already streamed is kept; the kill guarantees the run terminates instead of hanging forever.","triggerScenarios":"Watch-mode or server commands (npm run dev, --watch flags) under exec; tests hanging on network or a missing TTY prompt; a timeout left at default while the workload legitimately needs longer.","commonSituations":"Long builds in CI with tight defaults; interactive prompts blocking forever in non-interactive runs; flaky external dependencies stalling the command.","solutions":["Raise the timeout (see the exec command's --help for the exact flag) to fit the workload","Replace watch/serve-style commands with bounded ones (build instead of dev)","Find the hang: run the command bare under `timeout 30 ...` and inspect where it stalls","Give hanging prompts a non-interactive flag (--yes, CI=true) or feed stdin"],"exampleFix":"# before\ncodewhale exec -- npm run dev     # Command timed out after 30000ms\n\n# after\ncodewhale exec --timeout 300000 -- npm run build   # bounded workload (flag name per --help)","handlingStrategy":"retry","validationCode":"# gauge runtime before granting a budget\ntimeout 15 \"$CMD\" >/dev/null 2>&1; rc=$?\n[ $rc -eq 124 ] && echo 'command exceeds 15s -- raise exec timeout' >&2","typeGuard":null,"tryCatchPattern":"match run_sandboxed_exec(cmd, policy, timeout) {\n    Err(e) if e.to_string().contains(\"Command timed out\") => {\n        // re-run ONCE with a larger budget; a deterministic hang will not fix itself\n        run_sandboxed_exec(cmd, policy, timeout * 4)\n    }\n    other => other,\n}","preventionTips":["Never run watch/serve commands under a bounded exec; use one-shot equivalents","Set explicit generous timeouts in CI rather than relying on defaults","Give interactive tools a non-interactive flag so they cannot block on stdin"],"tags":["exec","timeout","subprocess","sandbox"],"backgroundTag":"command-timeout","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}