{"record":{"id":"69086fe9790eea89","repo":"sipeed/picoclaw","slug":"credential-cannot-determine-home-directory-w","errorCode":null,"errorMessage":"credential: cannot determine home directory: %w","messagePattern":"credential: cannot determine home directory: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/credential/keygen.go","lineNumber":19,"sourceCode":"package credential\n\nimport (\n\t\"crypto/ed25519\"\n\t\"crypto/rand\"\n\t\"encoding/pem\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"golang.org/x/crypto/ssh\"\n)\n\n// DefaultSSHKeyPath returns the canonical path for the picoclaw-specific SSH key.\n// The path is always ~/.ssh/picoclaw_ed25519.key (os.UserHomeDir is cross-platform).\nfunc DefaultSSHKeyPath() (string, error) {\n\thome, err := os.UserHomeDir()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"credential: cannot determine home directory: %w\", err)\n\t}\n\treturn filepath.Join(home, \".ssh\", \"picoclaw_ed25519.key\"), nil\n}\n\n// GenerateSSHKey generates an Ed25519 SSH key pair and writes the private key\n// to path (permissions 0600) and the public key to path+\".pub\" (permissions 0644).\n// The ~/.ssh/ directory is created with 0700 if it does not exist.\n// If the files already exist they are overwritten.\nfunc GenerateSSHKey(path string) error {\n\tif err := os.MkdirAll(filepath.Dir(path), 0o700); err != nil {\n\t\treturn fmt.Errorf(\"credential: keygen: cannot create directory %q: %w\", filepath.Dir(path), err)\n\t}\n\n\tpubRaw, privRaw, err := ed25519.GenerateKey(rand.Reader)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"credential: keygen: ed25519 key generation failed: %w\", err)\n\t}\n","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/pkg/credential/keygen.go#L1-L37","documentation":"DefaultSSHKeyPath calls os.UserHomeDir, which reads $HOME on Unix (%USERPROFILE% on Windows) and errors when it is empty. The picoclaw credential layer then cannot compute ~/.ssh/picoclaw_ed25519.key for key auto-detection or keygen defaulting. The underlying error is wrapped, so it is diagnosable via err.Error() text from the environment API.","triggerScenarios":"Calling DefaultSSHKeyPath (directly or via findDefaultSSHKey / GenerateSSHKey defaults) in a process whose environment lacks HOME: bare systemd services without Environment=, cron jobs, `sudo` without -E, docker run without -e HOME, env -i wrappers, or some CI runners.","commonSituations":"Deploying the daemon as a systemd unit and forgetting Environment=\"HOME=/var/lib/picoclaw\"; Docker images using USER without setting HOME for that uid; running via crontab where HOME may be unset; macOS launchd agents.","solutions":["Set HOME explicitly in the service environment: systemd `Environment=\"HOME=/var/lib/picoclaw\"`, docker `-e HOME=/root`, or `sudo -E`","Bypass home lookup entirely: export PICOCLAW_SSH_KEY_PATH=<absolute key path>, which pickSSHKeyPath honors before auto-detection","For containers, add `ENV HOME=/root` (or the USER's home) to the Dockerfile"],"exampleFix":"# before: systemd unit with no HOME\n[Service]\nExecStart=/usr/local/bin/picoclaw\n\n# after: explicit home (or bypass via key path env)\n[Service]\nEnvironment=\"HOME=/var/lib/picoclaw\"\n# alternative: Environment=\"PICOCLAW_SSH_KEY_PATH=/etc/picoclaw/picoclaw_ed25519.key\"\nExecStart=/usr/local/bin/picoclaw","handlingStrategy":"validation","validationCode":"func homeResolved() error {\n    if os.Getenv(\"HOME\") == \"\" { // covers the Unix UserHomeDir failure\n        return fmt.Errorf(\"HOME is not set; set HOME or PICOCLAW_SSH_KEY_PATH\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set HOME explicitly in systemd units, cron entries, and container envs","Prefer PICOCLAW_SSH_KEY_PATH for servers - it bypasses home-directory resolution entirely","In Dockerfiles, set ENV HOME when using USER with a nonstandard home","Smoke-test deployments with `env -i` locally to catch missing-env assumptions"],"tags":["environment","home-directory","systemd","containers","configuration"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}