{"record":{"id":"0a7306ffca43aeec","repo":"tinyhumansai/openhuman","slug":"failed-to-determine-user-home-directory","errorCode":null,"errorMessage":"Failed to determine user home directory","messagePattern":"Failed to determine user home directory","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/openhuman/config/migration_helpers/core.rs","lineNumber":271,"sourceCode":"        entries.push(SourceEntry {\n            key: normalize_key(file_stem, idx),\n            content: content.trim().to_string(),\n            category: MemoryCategory::Core,\n        });\n\n        idx += 1;\n    }\n\n    Ok(entries)\n}\n\nfn resolve_openclaw_workspace(source: Option<PathBuf>) -> Result<PathBuf> {\n    if let Some(path) = source {\n        return Ok(path);\n    }\n\n    let Some(user_dirs) = UserDirs::new() else {\n        bail!(\"Failed to determine user home directory\");\n    };\n\n    Ok(user_dirs.home_dir().join(\".openclaw\").join(\"workspace\"))\n}\n\nfn resolve_hermes_workspace(source: Option<PathBuf>) -> Result<PathBuf> {\n    if let Some(path) = source {\n        return Ok(path);\n    }\n\n    let Some(user_dirs) = UserDirs::new() else {\n        bail!(\"Failed to determine user home directory\");\n    };\n\n    #[cfg(windows)]\n    {\n        if let Some(local_app_data) = std::env::var_os(\"LOCALAPPDATA\") {\n            return Ok(PathBuf::from(local_app_data).join(\"hermes\"));","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/src/openhuman/config/migration_helpers/core.rs#L253-L289","documentation":"`resolve_openclaw_workspace` builds the default source path `~/.openclaw/workspace` from `directories::UserDirs::new()`. When the platform cannot determine a home directory that call returns None and the resolver bails before any migration work starts. An explicit `source` argument short-circuits resolution and never hits this error.","triggerScenarios":"Calling the OpenClaw migration without an explicit source path from a process whose home directory is not resolvable — HOME unset (scrubbed daemon/container environment), a service account without a profile, or unusual platform configurations.","commonSituations":"systemd units, docker containers, and CI runners with a minimal environment; running the core under a user with no passwd entry; hardened sandboxes that strip env vars.","solutions":["Pass the OpenClaw source workspace path explicitly to the migration call.","Set HOME (or the platform's home env var) for the process and retry.","Run the migration from a normal interactive user session."],"exampleFix":"# before — daemon with scrubbed env, default resolution fails\nExecStart=openhuman-core migrate openclaw\n\n# after — explicit source (or set HOME in the unit)\nExecStart=openhuman-core migrate openclaw --source /srv/openclaw/workspace\nEnvironment=HOME=/var/lib/openhuman","handlingStrategy":"validation","validationCode":"let source = match explicit_source {\n    Some(p) => p,\n    None => match directories::UserDirs::new() {\n        Some(u) => u.home_dir().join(\".openclaw\").join(\"workspace\"),\n        None => return Ok(None), // no home resolvable — require an explicit path\n    },\n};\nlet report = migrate_openclaw_memory(&config, Some(source), dry_run).await?;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass an explicit source path in headless/service contexts","Ensure HOME is set for daemons, containers, and CI runners","Run migrations from interactive user sessions where the home dir is guaranteed"],"tags":["migration","openclaw","home-directory","environment","service-accounts"],"backgroundTag":"missing-home-directory","analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}