{"record":{"id":"b3b043fd0ecc199c","repo":"BloopAI/vibe-kanban","slug":"child-process-has-no-stdin","errorCode":null,"errorMessage":"Child process has no stdin","messagePattern":"Child process has no stdin","errorType":"exception","errorClass":"ExecutorError","httpStatus":null,"severity":"error","filePath":"crates/executors/src/executors/acp/harness.rs","lineNumber":209,"sourceCode":"        cwd: PathBuf,\n        existing_session: Option<String>,\n        prompt: String,\n        exit_signal: Option<tokio::sync::oneshot::Sender<ExecutorExitResult>>,\n        session_namespace: String,\n        model: Option<String>,\n        mode: Option<String>,\n        approvals: Option<std::sync::Arc<dyn ExecutorApprovalService>>,\n        cancel: CancellationToken,\n    ) -> Result<(), ExecutorError> {\n        // Take child's stdio for ACP wiring\n        let orig_stdout = child.inner().stdout.take().ok_or_else(|| {\n            ExecutorError::Io(std::io::Error::new(\n                std::io::ErrorKind::NotFound,\n                \"Child process has no stdout\",\n            ))\n        })?;\n        let orig_stdin = child.inner().stdin.take().ok_or_else(|| {\n            ExecutorError::Io(std::io::Error::new(\n                std::io::ErrorKind::NotFound,\n                \"Child process has no stdin\",\n            ))\n        })?;\n\n        // Create a fresh stdout pipe for logs\n        let writer = crate::stdout_dup::create_stdout_pipe_writer(child)?;\n        let shared_writer = Arc::new(tokio::sync::Mutex::new(writer));\n        let (log_tx, mut log_rx) = mpsc::unbounded_channel::<String>();\n\n        // Spawn log -> stdout writer task\n        tokio::spawn(async move {\n            while let Some(line) = log_rx.recv().await {\n                let mut data = line.into_bytes();\n                data.push(b'\\n');\n                let mut w = shared_writer.lock().await;\n                let _ = w.write_all(&data).await;\n            }","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/BloopAI/vibe-kanban/blob/4deb7eca8f381f7cbc1f9d15515a9ab8f8009053/crates/executors/src/executors/acp/harness.rs#L191-L227","documentation":"bootstrap_acp_connection also takes the child's stdin to send ACP requests. If the child was spawned without a piped stdin, or its stdin was already taken, this error is returned. It mirrors the stdout check immediately above it in the same function.","triggerScenarios":"Calling bootstrap_acp_connection on a child spawned without Stdio::piped() for stdin, or a second bootstrap call after stdin was consumed by the first.","commonSituations":"Spawning the agent with stdin inherited from an interactive terminal or set to null; double initialization of the ACP harness; wrapper scripts consuming stdin before the protocol starts.","solutions":["Ensure the child is spawned with stdin(Stdio::piped()) as well as stdout.","Call bootstrap_acp_connection only once per child process.","Check that no wrapper script or prior harness consumed the agent's stdin.","Review the executor spawn path for the ACP configuration to confirm both pipes are requested."],"exampleFix":"// before\nlet child = cmd.spawn()?; // stdin defaults to inherit\n// after\ncmd.stdin(Stdio::piped());\nlet child = cmd.spawn()?;","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"fn has_piped_stdio(child: &Child) -> bool {\n    child.stdin.is_some() && child.stdout.is_some()\n}\nif !has_piped_stdio(&child) {\n    anyhow::bail!(\"child must be spawned with piped stdin/stdout\");\n}","tryCatchPattern":"match bootstrap_acp_connection(...).await {\n    Err(ExecutorError::Io(e)) if e.kind() == ErrorKind::NotFound\n        && e.to_string().contains(\"no stdin\") => {\n        // respawn the agent with Stdio::piped() stdin\n    }\n    other => other,\n}","preventionTips":["Set cmd.stdin(Stdio::piped()) whenever the executor runs in ACP mode.","Avoid wrapper scripts that read or redirect the agent's stdin.","Guard against double bootstrap — take() consumes the pipe the first time."],"tags":["process","stdio","acp","executor"],"backgroundTag":"missing-child-stdio-pipe","analyzedSha":"4deb7eca8f381f7cbc1f9d15515a9ab8f8009053","analyzedAt":"2026-08-29T09:24:13.446Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}