{"record":{"id":"16928ed34af50f14","repo":"chenhg5/cc-connect","slug":"get-home-dir-w","errorCode":null,"errorMessage":"get home dir: %w","messagePattern":"get home dir: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/matrix/e2ee.go","lineNumber":175,"sourceCode":"\n\t// Initialize SAS verification helper\n\tif p.autoVerify {\n\t\tif vErr := p.initVerification(ctx, ch); vErr != nil {\n\t\t\tslog.Warn(\"matrix: verification helper not available\", \"error\", vErr)\n\t\t} else {\n\t\t\tslog.Info(\"matrix: SAS verification enabled\", \"mode\", \"auto-verify\")\n\t\t}\n\t}\n}\n\nfunc (p *Platform) initCrypto(ctx context.Context, client *mautrix.Client) (*cryptohelper.CryptoHelper, error) {\n\tif client.DeviceID == \"\" {\n\t\treturn nil, fmt.Errorf(\"device ID not available from whoami\")\n\t}\n\n\thomeDir, err := os.UserHomeDir()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"get home dir: %w\", err)\n\t}\n\tcryptoDir := filepath.Join(homeDir, \".cc-connect\")\n\tif err := os.MkdirAll(cryptoDir, 0o700); err != nil {\n\t\treturn nil, fmt.Errorf(\"create data dir: %w\", err)\n\t}\n\tdbPath := filepath.Join(cryptoDir, fmt.Sprintf(\"matrix-crypto-%s.db\", client.DeviceID))\n\n\t// Derive a stable pickle key from the access token\n\th := sha256.Sum256([]byte(p.accessToken))\n\tpickleKey := make([]byte, 32)\n\tcopy(pickleKey, h[:])\n\n\treturn p.tryInitCrypto(ctx, client, pickleKey, dbPath, false)\n}\n\nfunc (p *Platform) tryInitCrypto(ctx context.Context, client *mautrix.Client, pickleKey []byte, dbPath string, isRetry bool) (*cryptohelper.CryptoHelper, error) {\n\tch, err := cryptohelper.NewCryptoHelper(client, pickleKey, dbPath)\n\tif err != nil {","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/matrix/e2ee.go#L157-L193","documentation":"initCrypto resolves the user's home directory via os.UserHomeDir() to locate the crypto store, and wraps any failure as \"get home dir: %w\". Go returns an error here when the HOME environment variable (Linux) or equivalent is unset or empty. The library cannot proceed to create the crypto database without it.","triggerScenarios":"Calling initE2EE/initCrypto in an environment where os.UserHomeDir() fails: $HOME (and $USER) unset on Linux, or no home directory for the running user.","commonSituations":"Running cc-connect under systemd with a minimal environment (no HOME); Docker containers running as a non-root user without a passwd entry; CI/cron environments stripping env vars.","solutions":["Set the HOME environment variable for the process (e.g. Environment=HOME=/home/user in systemd unit)","Run the service under a user with a valid passwd entry (User= in systemd) so UserHomeDir resolves","Use a fully-qualified shell like `getent passwd $(whoami)` to confirm the user has a home directory","Patch/rebuild to allow a configurable crypto data dir instead of deriving from home"],"exampleFix":"// systemd unit\n# before\n[Service]\nExecStart=/usr/bin/cc-connect\n// after\n[Service]\nUser=ccconnect\nEnvironment=HOME=/var/lib/ccconnect\nExecStart=/usr/bin/cc-connect","handlingStrategy":"validation","validationCode":"if home, err := os.UserHomeDir(); err != nil || home == \"\" {\n    return errors.New(\"HOME is not set; cannot locate crypto store directory\")\n}","typeGuard":"null","tryCatchPattern":"crypto, err := p.initCrypto(ctx, client)\nif err != nil {\n    if strings.Contains(err.Error(), \"get home dir\") {\n        slog.Warn(\"E2EE unavailable: HOME not set; set HOME or run under a real user\")\n        return nil // run without encryption\n    }\n    return fmt.Errorf(\"init e2ee: %w\", err)\n}","preventionTips":["Set Environment=HOME=... in systemd/docker unit files","Run services under a dedicated user with a valid home directory","Smoke-test os.UserHomeDir() at startup before enabling E2EE","Avoid stripping environment variables in minimal containers"],"tags":["matrix","e2ee","home-dir","environment"],"backgroundTag":"missing-env-var","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}