{"record":{"id":"c61163425d7a2614","repo":"Zackriya-Solutions/meetily","slug":"request-timed-out-after","errorCode":null,"errorMessage":"Request timed out after {:?}","messagePattern":"Request timed out after (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"frontend/src-tauri/src/summary/summary_engine/sidecar.rs","lineNumber":387,"sourceCode":"                .await\n                .context(\"Failed to write newline\")?;\n            stdin.flush().await.context(\"Failed to flush stdin\")?;\n        }\n\n        // Read response from stdout with timeout\n        match tokio::time::timeout(timeout, self.read_response()).await {\n            Ok(Ok(response)) => {\n                self.update_activity().await;\n                Ok(response)\n            }\n            Ok(Err(e)) => Err(e),\n            Err(_) => {\n                // Timeout reached - shutdown sidecar to stop generation\n                log::error!(\"Request timeout after {:?}, shutting down sidecar\", timeout);\n                if let Err(shutdown_err) = self.shutdown().await {\n                    log::error!(\"Failed to shutdown sidecar after timeout: {}\", shutdown_err);\n                }\n                Err(anyhow!(\"Request timed out after {:?}\", timeout))\n            }\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() {","sourceCodeStart":369,"sourceCodeEnd":405,"githubUrl":"https://github.com/Zackriya-Solutions/meetily/blob/0281737d87d26352fb0adc78c8c0975f691b23d1/frontend/src-tauri/src/summary/summary_engine/sidecar.rs#L369-L405","documentation":"send_request enforces a caller-supplied timeout over the whole round trip (write to stdin + read of the response line). On expiry it deliberately shuts the sidecar down to stop token generation, then returns this error - so a timeout also invalidates the process for subsequent requests.","triggerScenarios":"LLM inference on the loaded GGUF model takes longer than the passed Duration: long transcripts with a large model on CPU, the machine throttled (the sidecar runs under nice -n 10 on Unix / BELOW_NORMAL_PRIORITY_CLASS on Windows), or a timeout value set too small for the summary workload.","commonSituations":"First summary after loading a large model on CPU-only machines, hour-long meeting transcripts, contention with whisper transcription or other heavy processes on the same machine.","solutions":["Increase the timeout passed to send_request for summary workloads - CPU inference on a large model can take minutes","Switch to a smaller/faster summary model from the catalog","Shorten the prompt (truncate or chunk the transcript) before summarizing","Treat the error as non-retryable as-is: the sidecar is dead, so call ensure_running before the next request"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Size the timeout to the workload instead of a fixed constant\nlet est_tokens = transcript_len / 4;                       // rough token estimate\nlet timeout = Duration::from_secs(\n    (30 + est_tokens / tokens_per_second(model)).max(120).max(previous_timeout),\n);","typeGuard":null,"tryCatchPattern":"let mut attempt = 0;\nloop {\n    match sidecar.send_request(req.clone(), timeout).await {\n        Err(e) if e.to_string().contains(\"timed out\") && attempt < 2 => {\n            attempt += 1;\n            sidecar.ensure_running(model_path.clone()).await?; // sidecar was killed on timeout\n            continue;                                          // optionally with a larger timeout\n        }\n        other => break other,\n    }\n}?","preventionTips":["Remember the timeout path shuts the sidecar down: always respawn before retrying","Scale timeouts with transcript length and model size; CPU inference is minutes, not seconds","Run heavy summaries on a smaller model or chunk long transcripts to stay under the ceiling"],"tags":["sidecar","timeout","inference","performance"],"backgroundTag":"inference-timeout","analyzedSha":"0281737d87d26352fb0adc78c8c0975f691b23d1","analyzedAt":"2026-08-16T20:57:52.567Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}