{"record":{"id":"85952282fbdb3349","repo":"Hmbown/CodeWhale","slug":"could-not-resolve-spillover-path-empty-invalid-id","errorCode":null,"errorMessage":"could not resolve spillover path (empty/invalid id or missing home directory)","messagePattern":"could not resolve spillover path \\(empty/invalid id or missing home directory\\)","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/tools/truncate.rs","lineNumber":235,"sourceCode":"        return Ok(path);\n    }\n    if let Some(parent) = path.parent() {\n        fs::create_dir_all(parent)?;\n    }\n    crate::utils::write_atomic(&path, content.as_bytes())?;\n    Ok(path)\n}\n\n/// Write `content` to the spillover file for `id`. Creates the\n/// parent directory if needed. Returns the resolved path on success.\n///\n/// Atomic via `write` + filesystem rename guarantees from the\n/// underlying OS — the file is created at a temp name first and\n/// then renamed into place. Failures bubble up as `io::Error` so the\n/// caller can decide whether to surface them.\npub fn write_spillover(id: &str, content: &str) -> io::Result<PathBuf> {\n    let path = spillover_path(id).ok_or_else(|| {\n        io::Error::new(\n            io::ErrorKind::InvalidInput,\n            \"could not resolve spillover path (empty/invalid id or missing home directory)\",\n        )\n    })?;\n    if let Some(parent) = path.parent() {\n        fs::create_dir_all(parent)?;\n    }\n    crate::utils::write_atomic(&path, content.as_bytes())?;\n    Ok(path)\n}\n\n/// Drop spillover files older than `max_age`. Returns the number of\n/// files removed. Non-fatal: directory-missing returns 0; per-file\n/// errors are logged and skipped. Mirrors\n/// [`crate::session_manager::prune_workspace_snapshots`].\npub fn prune_older_than(max_age: Duration) -> io::Result<usize> {\n    let Some(root) = spillover_root() else {\n        return Ok(0);","sourceCodeStart":217,"sourceCodeEnd":253,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tools/truncate.rs#L217-L253","documentation":"write_spillover resolves the spillover file location from a session/content id via spillover_path. When the id is empty or otherwise invalid, or the user's home directory cannot be determined, spillover_path returns None and this InvalidInput io::Error is thrown before any file is written.","triggerScenarios":"Calling write_spillover with an empty string or an id spillover_path rejects (invalid characters/format); calling in an environment where the home directory cannot be resolved (dirs::home_dir() returns None).","commonSituations":"A session id that was never initialized (empty variable); running in a container or service context with no HOME set; passing user-controlled input as the id without validating it first.","solutions":["Ensure a non-empty, valid id is passed before calling write_spillover","Verify HOME (or the platform home directory) is set in the execution environment","Validate/normalize ids at the call site (e.g. reject empty or path-hostile characters)","Handle the error explicitly where the id's provenance is known instead of letting it bubble"],"exampleFix":"// before\nwrite_spillover(session_id, content)?;\n// after\nif session_id.is_empty() {\n    anyhow::bail!(\"cannot spill over: session id is empty\");\n}\nwrite_spillover(session_id, content)?;","handlingStrategy":"validation","validationCode":"if id.is_empty() {\n    anyhow::bail!(\"spillover id must be non-empty\");\n}\nif std::env::var_os(\"HOME\").is_none() {\n    anyhow::bail!(\"HOME is not set; cannot resolve spillover path\");\n}","typeGuard":"fn is_valid_spillover_id(id: &str) -> bool {\n    !id.is_empty() && id.chars().all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_')\n}","tryCatchPattern":"match write_spillover(id, content) {\n    Ok(path) => path,\n    Err(e) if e.kind() == io::ErrorKind::InvalidInput => {\n        eprintln!(\"bad spillover id {id:?} or missing home dir\");\n        return;\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Validate ids at the boundary where they are created, not at write time","Guarantee HOME is set in service/container environments","Centralize id generation so empty ids cannot occur","Unit-test the home-directory-absent path"],"tags":["io","invalid-input","path-resolution","home-directory"],"backgroundTag":"invalid-argument-value","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}