{"record":{"id":"680f80d393c8c8c0","repo":"Zackriya-Solutions/meetily","slug":"sidecar-closed-stdout-process-may-have-crashed","errorCode":null,"errorMessage":"Sidecar closed stdout (process may have crashed)","messagePattern":"Sidecar closed stdout \\(process may have crashed\\)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"critical","filePath":"frontend/src-tauri/src/summary/summary_engine/sidecar.rs","lineNumber":406,"sourceCode":"            }\n        }\n    }\n\n    /// Read a single line response from stdout\n    async fn read_response(&self) -> Result<String> {\n        let mut stdout_lock = self.stdout_reader.lock().await;\n        let reader = stdout_lock\n            .as_mut()\n            .ok_or_else(|| anyhow!(\"Sidecar not running\"))?;\n\n        let mut line = String::new();\n        reader\n            .read_line(&mut line)\n            .await\n            .context(\"Failed to read response from stdout\")?;\n\n        if line.is_empty() {\n            return Err(anyhow!(\"Sidecar closed stdout (process may have crashed)\"));\n        }\n\n        Ok(line.trim().to_string())\n    }\n\n    /// Send ping to keep sidecar alive\n    async fn send_ping(&self) -> Result<()> {\n        let request = serde_json::json!({\"type\": \"ping\"}).to_string();\n        let timeout = Duration::from_secs(5);\n\n        // Note: We don't use send_request here to avoid incrementing active_request_count\n        // for internal health checks, as that would prevent graceful shutdown\n        \n        // Write request\n        {\n            let mut stdin_lock = self.stdin_writer.lock().await;\n            if let Some(stdin) = stdin_lock.as_mut() {\n                stdin.write_all(request.as_bytes()).await?;","sourceCodeStart":388,"sourceCodeEnd":424,"githubUrl":"https://github.com/Zackriya-Solutions/meetily/blob/0281737d87d26352fb0adc78c8c0975f691b23d1/frontend/src-tauri/src/summary/summary_engine/sidecar.rs#L388-L424","documentation":"read_response got EOF on the sidecar's stdout: read_line returned zero bytes, meaning the llama-helper process has exited. The helper crashed or was killed - fatal model-load error inside the helper, a panic, the OOM killer, or an external kill. stderr is inherited (Stdio::inherit), so the helper's own dying message usually appears in the app log just before this error.","triggerScenarios":"llama-helper dies while handling a request: out-of-memory loading or running a large GGUF, a panic in the helper, an invalid/unreadable model path passed at spawn, or an external signal (OOM killer, task manager, container cgroup kill).","commonSituations":"Large model on machines with tight RAM (OOM kill), model file deleted or moved after the sidecar loaded it, helper binary built from a different source revision whose stdin/stdout protocol no longer matches the app.","solutions":["Check the app log for the helper's stderr immediately before the EOF - it names the real cause (model load failure, allocation failure, panic)","If memory was the cause, free RAM or use a smaller summary model","Verify the model path passed to ensure_running still exists and is a valid GGUF","Rebuild llama-helper from the same source revision as the app so the JSON-line protocol matches"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Pre-flight: the model must be readable and the process alive before sending\nif !model_path.is_file() { return Err(anyhow!(\"model file missing: {:?}\", model_path)); }\nif !sidecar.is_healthy() { sidecar.ensure_running(model_path.clone()).await?; }","typeGuard":null,"tryCatchPattern":"match sidecar.send_request(req, timeout).await {\n    Err(e) if e.to_string().contains(\"closed stdout\") => {\n        log::error!(\"sidecar crashed; stderr (inherited) shows the cause just above\");\n        sidecar.ensure_running(model_path.clone()).await?; // respawn\n        match sidecar.send_request(req, timeout).await {\n            Err(e2) if e2.to_string().contains(\"closed stdout\") =>\n                Err(anyhow!(\"sidecar crashes immediately; check RAM and rebuild llama-helper\")),\n            other => other,\n        }\n    }\n    other => other,\n}?","preventionTips":["Watch the app log (stderr is inherited) for the helper's own crash message before this EOF error","Keep helper and app built from the same source revision so the line protocol matches","Cap model size to available RAM; an OOM-killed helper is the most common crash cause"],"tags":["sidecar","crash","stdout","oom","process"],"backgroundTag":"child-process-crashed","analyzedSha":"0281737d87d26352fb0adc78c8c0975f691b23d1","analyzedAt":"2026-08-16T20:57:52.567Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}