{"record":{"id":"71d49bf3feddad47","repo":"tinyhumansai/openhuman","slug":"worker-protocol-connection-timed-out","errorCode":null,"errorMessage":"{} worker protocol connection timed out","messagePattern":"(.+?) worker protocol connection timed out","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/openhuman/runtime/pool/worker.rs","lineNumber":156,"sourceCode":"            .spawn()\n            .with_context(|| format!(\"spawning {} worker\", launch.lang.id()))?;\n        let child_stdin = child.stdin.take();\n        let stdout = child.stdout.take().context(\"worker stdout missing\")?;\n        if let Some(stderr) = child.stderr.take() {\n            drain_stderr(launch.lang, stderr);\n        }\n        let (stdin, reader, expected_token): (\n            Box<dyn AsyncWrite + Send + Unpin>,\n            Box<dyn AsyncRead + Send + Unpin>,\n            Option<String>,\n        ) = if let Some((listener, token)) = isolated_protocol {\n            // stdout is now exclusively user fd-level output. Drain it so\n            // chatty jobs cannot block; protocol frames use the socket.\n            drain_stdout(launch.lang, stdout);\n            let (stream, _) = tokio::time::timeout(HANDSHAKE_TIMEOUT, listener.accept())\n                .await\n                .map_err(|_| {\n                    anyhow::anyhow!(\"{} worker protocol connection timed out\", launch.lang.id())\n                })?\n                .context(\"accepting isolated worker protocol connection\")?;\n            let (reader, writer) = tokio::io::split(stream);\n            (Box::new(writer), Box::new(reader), Some(token))\n        } else {\n            (\n                Box::new(child_stdin.context(\"worker stdin missing\")?),\n                Box::new(stdout),\n                None,\n            )\n        };\n        let mut lines = BufReader::new(reader).lines();\n\n        let ready_line = match tokio::time::timeout(HANDSHAKE_TIMEOUT, lines.next_line()).await {\n            Ok(Ok(Some(line))) => line,\n            Ok(Ok(None)) => bail!(\n                \"{} worker exited before readiness handshake\",\n                launch.lang.id()","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/src/openhuman/runtime/pool/worker.rs#L138-L174","documentation":"Establishing the protocol connection to a freshly spawned language-runtime worker timed out — the child process started, but it never completed the handshake (token exchange / readiness signal on stdout) within the allotted window. This fires when the worker binary is slow to boot (cold cache, heavy runtime init), hangs on startup (missing runtime dependencies, stuck module loading), or died without writing to stderr in a way the drain caught. The language id is interpolated into the message.","triggerScenarios":"Thrown at src/openhuman/runtime/pool/worker.rs:156 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Retry the operation — cold-start slowness often succeeds on a second attempt once caches are warm","Check the worker runtime's dependencies are installed and its binary launches standalone","For chronically slow starts, look for a configurable startup-timeout setting in the pool settings"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}