{"record":{"id":"36aeb5227efd8c10","repo":"jdx/mise","slug":"timed-out-after-timeout-36aeb5","errorCode":null,"errorMessage":"timed out after {timeout:?}","messagePattern":"timed out after (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/bounded.rs","lineNumber":49,"sourceCode":"        // allocate twice what was asked before anyone objected.\n        let budget = AtomicUsize::new(limit);\n        let result = tokio::time::timeout(timeout, async {\n            tokio::try_join!(\n                child.wait(),\n                capture(stdout, &budget, limit),\n                capture(stderr, &budget, limit)\n            )\n        })\n        .await;\n        let (status, stdout, _stderr) = match result {\n            Ok(Ok(output)) => output,\n            Ok(Err(err)) => {\n                end(&mut child, tree).await;\n                return Err(err.into());\n            }\n            Err(_) => {\n                end(&mut child, tree).await;\n                bail!(\"timed out after {timeout:?}\");\n            }\n        };\n        if !status.success() {\n            bail!(\"command exited with non-zero status: {status}\");\n        }\n        Ok(String::from_utf8(stdout)?.trim_end().to_string())\n    }\n}\n\n/// How long reaping a killed command may take before it is left to the\n/// operating system. A process that has been killed is normally gone at\n/// once; one that is not is no reason to outlive the deadline.\nconst REAP: Duration = Duration::from_secs(1);\n\n/// End the command and account for it, without waiting on a process that\n/// may not be listening. Closing the tree kills the group, but the direct\n/// child can be outside it — on Windows it may never have joined the job,\n/// and on unix it can have left the group — and `kill_on_drop` cannot run","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/cmd/bounded.rs#L31-L67","documentation":"Raised by the bounded/isolated command reader (read_isolated in src/cmd/bounded.rs) when the spawned child does not finish before the configured timeout elapses. The child process and its process tree are killed first (end()), then a timeout error is returned. It guards mise against hanging on a stuck subprocess.","triggerScenarios":"Any call into read_isolated where the child command blocks (reads stdin, waits on network, deadlock) longer than the `timeout` duration passed to the function.","commonSituations":"A tool-version listing command hangs on a slow/unreachable network; a plugin script prompts for input while stdin is captured; a wedged daemon holds the child open.","solutions":["Increase the timeout value at the call site if the command is legitimately slow","Fix the underlying command so it completes unattended (remove interactive prompts)","Check network/proxy availability if the command fetches remote data","Investigate the stuck process tree; the child is killed, so look at what it was waiting on"],"exampleFix":"// before\nread_isolated(&mut cmd, Duration::from_secs(5), &tree).await?\n// after\nread_isolated(&mut cmd, Duration::from_secs(60), &tree).await?","handlingStrategy":"try-catch","validationCode":"// ensure the command can run unattended and quickly: smoke-test it first\n// e.g. time out manually before wiring it into mise\ntimeout 10 <command> --version || echo \"command may hang\"","typeGuard":null,"tryCatchPattern":"match read_isolated(&mut cmd, timeout, &tree).await {\n    Ok(out) => out,\n    Err(e) if e.to_string().starts_with(\"timed out after\") => {\n        // retry once with a larger timeout or fall back to a cached value\n        retry_with_timeout(timeout * 4).await.unwrap_or_else(|_| cached_value())\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Set realistic timeouts for commands that hit the network","Never rely on interactive commands for isolated reads","Cache previous successful output as a fallback","Monitor for wedged processes if timeouts recur"],"tags":["timeout","subprocess","process-tree"],"backgroundTag":"request-timeout","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"}