{"record":{"id":"44bc29dc7762702c","repo":"Hmbown/CodeWhale","slug":"could-not-resolve-session-artifact-path-missing-home","errorCode":null,"errorMessage":"could not resolve session artifact path (missing home directory)","messagePattern":"could not resolve session artifact path \\(missing home directory\\)","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/artifacts.rs","lineNumber":142,"sourceCode":"    {\n        return None;\n    }\n    Some(\n        artifact_sessions_root()?\n            .join(session_id)\n            .join(relative_path),\n    )\n}\n\npub fn write_session_artifact(\n    session_id: &str,\n    artifact_id: &str,\n    content: &str,\n) -> io::Result<(PathBuf, PathBuf)> {\n    let relative_path = session_artifact_relative_path(artifact_id);\n    let absolute_path =\n        session_artifact_absolute_path(session_id, &relative_path).ok_or_else(|| {\n            io::Error::new(\n                io::ErrorKind::InvalidInput,\n                \"could not resolve session artifact path (missing home directory)\",\n            )\n        })?;\n    if let Some(parent) = absolute_path.parent() {\n        std::fs::create_dir_all(parent)?;\n    }\n    crate::utils::write_atomic(&absolute_path, content.as_bytes())?;\n    Ok((absolute_path, relative_path))\n}\n\n/// Publish immutable session-owned bytes without replacing an earlier handle.\n/// A duplicate replay with identical bytes is idempotent; a different payload\n/// for the same relative path fails closed.\npub fn write_session_relative_immutable(\n    session_id: &str,\n    relative_path: &Path,\n    content: &[u8],","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/artifacts.rs#L124-L160","documentation":"Public entry `write_session_artifact` builds an absolute artifact path under the user's home directory. When the home directory cannot be resolved, `session_artifact_absolute_path` returns None and this InvalidInput io::Error is thrown instead of writing the file.","triggerScenarios":"Calling `write_session_artifact` in an environment where the home directory is unavailable: HOME unset, no passwd entry for the user, or running in a stripped container/service context.","commonSituations":"Running under systemd with no HOME, inside minimal Docker images, cron jobs without a full environment, or CI sandboxes without user home directories.","solutions":["Set HOME to an existing writable directory for the process (e.g. `export HOME=/home/user` or systemd `Environment=HOME=...`).","Run under a user account that has a valid home directory in /etc/passwd.","In containers, create the home directory and pass it explicitly.","Prefer APIs that accept an explicit base directory if operating in a headless service context."],"exampleFix":"// before (systemd unit)\n[Service]\nExecStart=/usr/local/bin/codewhale\n\n// after\n[Service]\nEnvironment=HOME=/var/lib/codewhale\nExecStart=/usr/local/bin/codewhale","handlingStrategy":"validation","validationCode":"fn artifact_env_ready() -> bool {\n    std::env::var_os(\"HOME\").map(|h| !h.is_empty()).unwrap_or(false)\n}","typeGuard":"fn home_dir() -> Option<std::path::PathBuf> {\n    std::env::var_os(\"HOME\").filter(|h| !h.is_empty()).map(std::path::PathBuf::from)\n}","tryCatchPattern":"match write_session_artifact(session, id, content) {\n    Err(e) if e.to_string().contains(\"missing home directory\") => {\n        // configure HOME or switch to an explicit-root API\n    }\n    other => other?,\n}","preventionTips":["Set HOME explicitly in service units, containers, and cron.","Verify home resolution at startup in headless deployments.","Prefer explicit-root APIs for daemons."],"tags":["filesystem","environment","artifacts"],"backgroundTag":"missing-env-var","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T10:30:35.592Z"}