{"record":{"id":"2ceb0d0b91b90db1","repo":"Hmbown/CodeWhale","slug":"workspace-env-fifo-blocked-startup-timeout","errorCode":null,"errorMessage":"workspace .env FIFO blocked startup: {timeout}","messagePattern":"workspace \\.env FIFO blocked startup: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/lib.rs","lineNumber":17682,"sourceCode":"        let worker = std::thread::spawn(move || {\n            let result = load_workspace_dotenv_credentials_from_path(&worker_path)\n                .map(|_| \"unexpected success\".to_string())\n                .unwrap_or_else(|error| error.to_string());\n            tx.send(result).expect(\"send loader result\");\n        });\n\n        let error = match rx.recv_timeout(Duration::from_secs(1)) {\n            Ok(error) => error,\n            Err(timeout) => {\n                // Release a regressed blocking reader so the test can fail\n                // promptly instead of leaving a stuck process behind.\n                let _writer = std::fs::OpenOptions::new()\n                    .write(true)\n                    .open(&dotenv)\n                    .expect(\"open fifo writer to release blocked reader\");\n                let _ = rx.recv_timeout(Duration::from_secs(1));\n                worker.join().expect(\"join released loader\");\n                panic!(\"workspace .env FIFO blocked startup: {timeout}\");\n            }\n        };\n        worker.join().expect(\"join loader\");\n\n        assert!(error.contains(\"not a regular file\"), \"{error}\");\n    }\n\n    #[test]\n    fn exec_json_conflicts_with_stream_json_output() {\n        let err = Cli::try_parse_from([\n            \"codewhale\",\n            \"exec\",\n            \"--json\",\n            \"--output-format\",\n            \"stream-json\",\n            \"hello\",\n        ])\n        .expect_err(\"json summary and stream-json must not mix\");","sourceCodeStart":17664,"sourceCodeEnd":17700,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/crates/tui/src/lib.rs#L17664-L17700","documentation":"A test-timeout panic inside a workspace .env loading test. The test creates a FIFO (named pipe) where a real .env file would be, starts the loader in a worker thread, and expects the loader to fail fast with 'not a regular file'. If the loader instead blocks on reading the FIFO, the receiver times out after 1 second and the test panics with 'workspace .env FIFO blocked startup: {timeout}', which also opens a writer to unblock and join the worker.","triggerScenarios":"The .env loader blocks reading a FIFO instead of rejecting it; rx.recv_timeout(1s) elapses without the expected error being sent, hitting the panic in the timeout arm.","commonSituations":"A developer replaces the regular-file check (metadata().is_file()) with a streaming read; a regression lets startup hang on a FIFO or device file placed at the workspace .env path; slow CI makes the 1-second timeout too tight.","solutions":["Restore an explicit regular-file validation (fs::metadata + is_file) in the workspace .env loader before opening the file.","Ensure the loader rejects non-regular files with an error containing 'not a regular file' rather than attempting to read.","If the failure is a flaky timeout on slow machines, raise the recv_timeout budget or the Duration used in the panic message.","Re-run the single test to confirm the loader now fails fast on FIFOs."],"exampleFix":"// before\nlet contents = std::fs::read_to_string(&dotenv)?;\n// after\nlet meta = std::fs::metadata(&dotenv)?;\nif !meta.is_file() {\n    return Err(anyhow!(\"workspace .env is not a regular file\"));\n}\nlet contents = std::fs::read_to_string(&dotenv)?;","handlingStrategy":"validation","validationCode":"let meta = std::fs::metadata(&dotenv_path).ok()?;\nif !meta.is_file() {\n    return Err(\"workspace .env is not a regular file\");\n}","typeGuard":"fn is_regular_file(p: &std::path::Path) -> bool {\n    std::fs::metadata(p).map(|m| m.is_file()).unwrap_or(false)\n}","tryCatchPattern":"match std::fs::metadata(&dotenv) {\n    Ok(m) if m.is_file() => load_dotenv(&dotenv),\n    _ => return Err(anyhow!(\"workspace .env is not a regular file\")),\n}","preventionTips":["Always stat the .env path before opening it; never stream-read blindly","Reject FIFOs, devices, and sockets at startup with a clear error","Keep loader startup non-blocking; bound any read with a timeout","Test with special files (FIFO/dev) in CI to catch regressions"],"tags":["rust","testing","timeout","dotenv","blocking"],"backgroundTag":"request-timeout","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}