{"record":{"id":"76f6fd8326d13b4f","repo":"warpdotdev/warp","slug":"could-not-determine-home-directory-76f6fd","errorCode":null,"errorMessage":"could not determine home directory","messagePattern":"could not determine home directory","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/src/ai/agent_sdk/driver/harness/claude_transcript.rs","lineNumber":95,"sourceCode":"/// Claude CLI convention of replacing every `/` with `-`.\n///\n/// Example: `/Users/ben/src/foo` → `-Users-ben-src-foo`\npub(crate) fn encode_cwd(cwd: &Path) -> String {\n    cwd.to_string_lossy().replace(['/', '.'], \"-\")\n}\n\n/// Resolve the Claude config directory.\n///\n/// Reads `$CLAUDE_CONFIG_DIR` if set, otherwise falls back to `~/.claude`.\n//\n/// TODO(REMOTE-1209): Use the transcript path reported by our hook.\npub(crate) fn claude_config_dir() -> Result<PathBuf> {\n    if let Ok(dir) = std::env::var(\"CLAUDE_CONFIG_DIR\") {\n        return Ok(PathBuf::from(dir));\n    }\n    home_dir_for_claude_config()\n        .map(|h| h.join(\".claude\"))\n        .ok_or_else(|| anyhow::anyhow!(\"could not determine home directory\"))\n}\n\n/// In tests on Windows, `dirs::home_dir()` ignores `HOME`, so we check it\n/// manually so that tests can override the home directory.\npub(super) fn home_dir_for_claude_config() -> Option<PathBuf> {\n    #[cfg(test)]\n    if let Some(home) = std::env::var_os(\"HOME\")\n        && !home.is_empty()\n    {\n        return Some(PathBuf::from(home));\n    }\n    dirs::home_dir()\n}\n\n/// Assemble a [`ClaudeTranscriptEnvelope`] from the Claude config directory.\n///\n/// Reads:\n/// - `<config_root>/projects/<encoded_cwd>/<session_uuid>.jsonl` - main transcript","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/warpdotdev/warp/blob/e72fd7aacbbb2236d9b3be2aad7e7178fe94b4bc/app/src/ai/agent_sdk/driver/harness/claude_transcript.rs#L77-L113","documentation":"Thrown by claude_config_dir() (claude_transcript.rs) when CLAUDE_CONFIG_DIR is unset and home_dir_for_claude_config() yields None. The transcript machinery uses this directory (~/.claude) to locate Claude Code session rollout files, so transcript hydration for a session cannot proceed.","triggerScenarios":"Resolving Claude transcripts for a conversation (finding session jsonl files, continuation commands) with CLAUDE_CONFIG_DIR unset/empty and no home directory — unset HOME on Unix, unset USERPROFILE on Windows, or getpwuid failing for the runtime user.","commonSituations":"Same class as the other home-dir errors: containers, CI, systemd services, or sandboxes where HOME was stripped; also note the code reads CLAUDE_CONFIG_DIR without an emptiness check here, so CLAUDE_CONFIG_DIR=\"\" still falls through to the failing home lookup.","solutions":["Set CLAUDE_CONFIG_DIR to the directory holding the .claude session data (or at least a writable dir) in the agent environment.","Otherwise ensure HOME/USERPROFILE is set to a valid, readable path.","If transcripts live elsewhere on your setup, point CLAUDE_CONFIG_DIR there so session discovery works."],"exampleFix":"# before\nunset HOME; warp agent …  # transcript resolution fails\n\n# after\nexport CLAUDE_CONFIG_DIR=/var/lib/warp/claude   # or set HOME=/root\nwarp agent …","handlingStrategy":"validation","validationCode":"let dir = std::env::var(\"CLAUDE_CONFIG_DIR\").ok().filter(|d| !d.is_empty());\nanyhow::ensure!(dir.is_some() || dirs::home_dir().is_some(), \"set CLAUDE_CONFIG_DIR or HOME for transcript resolution\");","typeGuard":"fn claude_transcripts_locatable() -> bool {\n    std::env::var(\"CLAUDE_CONFIG_DIR\").map(|d| !d.is_empty()).unwrap_or(false) || dirs::home_dir().is_some()\n}","tryCatchPattern":"match claude_config_dir() {\n    Err(err) if err.to_string().contains(\"could not determine home directory\") => {\n        // no transcript dir → skip hydration instead of failing the whole session\n        Ok(None)\n    }\n    rest => rest.map(Some),\n}","preventionTips":["Set CLAUDE_CONFIG_DIR when session data lives outside the default ~/.claude.","Keep HOME defined in the process resolving transcripts.","Note CLAUDE_CONFIG_DIR=\"\" is treated as unset here — export a real path."],"tags":["environment","home-directory","claude-code","transcripts","rust"],"backgroundTag":null,"analyzedSha":"e72fd7aacbbb2236d9b3be2aad7e7178fe94b4bc","analyzedAt":"2026-08-16T08:27:25.381Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}