chenhg5/cc-connect · error
get home dir
Error message
get home dir: %w
What it means
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.
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
Example fix
// systemd unit # before [Service] ExecStart=/usr/bin/cc-connect // after [Service] User=ccconnect Environment=HOME=/var/lib/ccconnect ExecStart=/usr/bin/cc-connect
Defensive patterns
Strategy: validation
Validate before calling
if home, err := os.UserHomeDir(); err != nil || home == "" {
return errors.New("HOME is not set; cannot locate crypto store directory")
} Type guard
null
Try / catch
crypto, err := p.initCrypto(ctx, client)
if err != nil {
if strings.Contains(err.Error(), "get home dir") {
slog.Warn("E2EE unavailable: HOME not set; set HOME or run under a real user")
return nil // run without encryption
}
return fmt.Errorf("init e2ee: %w", err)
} Prevention
- 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
When it happens
Trigger: Calling initE2EE/initCrypto in an environment where os.UserHomeDir() fails: $HOME (and $USER) unset on Linux, or no home directory for the running user.
Common situations: 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.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- create crypto helper
- create data dir
- device ID not available from whoami
- gemini: cannot determine home dir
- get home dir
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/16928ed34af50f14.
Report an issue: GitHub.
Appendix: source
Thrown at platform/matrix/e2ee.go:175
// Initialize SAS verification helper
if p.autoVerify {
if vErr := p.initVerification(ctx, ch); vErr != nil {
slog.Warn("matrix: verification helper not available", "error", vErr)
} else {
slog.Info("matrix: SAS verification enabled", "mode", "auto-verify")
}
}
}
func (p *Platform) initCrypto(ctx context.Context, client *mautrix.Client) (*cryptohelper.CryptoHelper, error) {
if client.DeviceID == "" {
return nil, fmt.Errorf("device ID not available from whoami")
}
homeDir, err := os.UserHomeDir()
if err != nil {
return nil, fmt.Errorf("get home dir: %w", err)
}
cryptoDir := filepath.Join(homeDir, ".cc-connect")
if err := os.MkdirAll(cryptoDir, 0o700); err != nil {
return nil, fmt.Errorf("create data dir: %w", err)
}
dbPath := filepath.Join(cryptoDir, fmt.Sprintf("matrix-crypto-%s.db", client.DeviceID))
// Derive a stable pickle key from the access token
h := sha256.Sum256([]byte(p.accessToken))
pickleKey := make([]byte, 32)
copy(pickleKey, h[:])
return p.tryInitCrypto(ctx, client, pickleKey, dbPath, false)
}
func (p *Platform) tryInitCrypto(ctx context.Context, client *mautrix.Client, pickleKey []byte, dbPath string, isRetry bool) (*cryptohelper.CryptoHelper, error) {
ch, err := cryptohelper.NewCryptoHelper(client, pickleKey, dbPath)
if err != nil {View on GitHub (pinned to 4000b2338a)