{"record":{"id":"f8e35e0f61735d6f","repo":"FuelLabs/sway","slug":"unable-to-find-the-user-home-directory","errorCode":null,"errorMessage":"unable to find the user home directory","messagePattern":"unable to find the user home directory","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"forc-util/src/lib.rs","lineNumber":221,"sourceCode":"    if restricted::is_non_ascii_name(name) {\n        bail!(\"the name `{name}` contains non-ASCII characters which are unsupported\");\n    }\n    Ok(())\n}\n\n/// Simple function to convert kebab-case to snake_case.\npub fn kebab_to_snake_case(s: &str) -> String {\n    s.replace('-', \"_\")\n}\n\npub fn default_output_directory(manifest_dir: &Path) -> PathBuf {\n    manifest_dir.join(DEFAULT_OUTPUT_DIRECTORY)\n}\n\n/// Returns the user's `.forc` directory, `$HOME/.forc` by default.\npub fn user_forc_directory() -> PathBuf {\n    dirs::home_dir()\n        .expect(\"unable to find the user home directory\")\n        .join(constants::USER_FORC_DIRECTORY)\n}\n\n/// The location at which `forc` will checkout git repositories.\npub fn git_checkouts_directory() -> PathBuf {\n    user_forc_directory().join(\"git\").join(\"checkouts\")\n}\n\n/// Given a path to a directory we wish to lock, produce a path for an associated lock file.\n///\n/// Note that the lock file itself is simply a placeholder for co-ordinating access. As a result,\n/// we want to create the lock file if it doesn't exist, but we can never reliably remove it\n/// without risking invalidation of an existing lock. As a result, we use a dedicated, hidden\n/// directory with a lock file named after the checkout path.\n///\n/// Note: This has nothing to do with `Forc.lock` files, rather this is about fd locks for\n/// coordinating access to particular paths (e.g. git checkout directories).\nfn fd_lock_path<X: AsRef<Path>>(path: X) -> PathBuf {","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/FuelLabs/sway/blob/47e5e902faa42baf652dd6a0c88cd23390c1a614/forc-util/src/lib.rs#L203-L239","documentation":"forc-util's user_forc_directory() computes $HOME/.forc, the base for git checkouts, caches and several defaults across the forc toolchain. dirs::home_dir() returns None when HOME is unset (Unix) or the user profile cannot be determined (Windows), and this expect panics, taking down whatever forc command reached the call.","triggerScenarios":"Running any forc command in a container, service, or cron context where HOME is unset (docker run without -e HOME, systemd unit without Environment, `sudo -E` stripping); running as a user with no passwd home entry; CI runners that clear the environment.","commonSituations":"Dockerfiles that set USER without providing HOME; Kubernetes/CI pods with minimal env; scheduled tasks; building inside sandboxed agents that drop env vars.","solutions":["Set HOME explicitly for the build context: `docker run -e HOME=/root ...` or `export HOME=$PWD/.home` in CI scripts.","For services, add `Environment=\"HOME=/path\"` to the unit file or ensure the run user has a home directory in /etc/passwd.","Create and persist the directory you point HOME at so .forc caches survive between runs."],"exampleFix":"# before\n$ docker run --rm myimg forc build\nthread 'main' panicked: unable to find the user home directory\n# after\n$ docker run --rm -e HOME=/root -v forc-cache:/root/.forc myimg forc build","handlingStrategy":"validation","validationCode":"# container/CI entrypoint: guarantee HOME before any forc command\nif [ -z \"${HOME:-}\" ]; then\n  export HOME=\"$PWD/.home\"\n  mkdir -p \"$HOME\"\nfi\nforc build","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass -e HOME (and a writable volume for /root/.forc) in docker runs.","Set Environment=\"HOME=...\" in systemd units and export HOME in cron entries.","Smoke-test with `forc --version` plus a trivial build in new minimal environments to catch this early."],"tags":["rust","forc","forc-util","home-directory","panic","environment","containers","ci"],"backgroundTag":null,"analyzedSha":"47e5e902faa42baf652dd6a0c88cd23390c1a614","analyzedAt":"2026-08-16T07:57:45.555Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}