multica-ai/multica · error
resolve %s %q: user home: %w
Error message
resolve %s %q: user home: %w
What it means
resolveCodexConfigPath expands a ~/ or ~\-prefixed config path and needs the current user's home directory; os.UserHomeDir failed, typically because $HOME (or %USERPROFILE% on Windows) is unset or empty in the daemon's environment.
Source
Thrown at server/internal/daemon/execenv/codex_home.go:1222
return fmt.Errorf("close codex models cache binding %s: %w", path, err)
}
return nil
}
// resolveCodexConfigPath maps a path-valued config.toml entry to its source
// file on this host. key is the config key the path came from and only shapes
// the diagnostics, so an operator reading a failure knows which setting to fix.
// A relative path resolves against the shared Codex home — that is the
// directory the config was copied from, and the base Codex itself would have
// used before the per-task home relocated CODEX_HOME.
func resolveCodexConfigPath(configPath, sharedHome, key string) (string, error) {
if filepath.IsAbs(configPath) {
return filepath.Clean(configPath), nil
}
if strings.HasPrefix(configPath, "~/") || strings.HasPrefix(configPath, `~\`) {
home, err := os.UserHomeDir()
if err != nil {
return "", fmt.Errorf("resolve %s %q: user home: %w", key, configPath, err)
}
return filepath.Join(home, configPath[2:]), nil
}
if strings.HasPrefix(configPath, "~") {
return "", fmt.Errorf("%s %q uses unsupported ~user expansion", key, configPath)
}
return filepath.Join(sharedHome, filepath.Clean(configPath)), nil
}
func exposeSharedCodexPluginCache(codexHome, sharedHome string) error {
src := filepath.Join(sharedHome, "plugins", "cache")
dst := filepath.Join(codexHome, "plugins", "cache")
if err := os.MkdirAll(src, 0o755); err != nil {
return fmt.Errorf("create shared plugin cache dir: %w", err)
}
if err := os.MkdirAll(filepath.Dir(dst), 0o755); err != nil {
return fmt.Errorf("create codex plugin dir: %w", err)
}View on GitHub (pinned to 2c0912b6ec)
Solutions
- Set HOME (or USERPROFILE on Windows) in the daemon's service environment
- Change the Codex config value to an absolute path instead of ~/...
- Run the daemon under a properly provisioned user account
Example fix
// before (config.toml) model_provider_file = "~/codex/providers.json" // after model_provider_file = "/home/daemon/codex/providers.json"
Defensive patterns
Strategy: validation
Validate before calling
if os.UserHomeDir() != nil {
return fmt.Errorf("HOME unset; cannot resolve ~/ paths in codex config")
} Prevention
- Set HOME/USERPROFILE in the daemon service environment
- Prefer absolute paths in daemon-consumed Codex config
When it happens
Trigger: Daemon process launched by systemd or a container without HOME set; environment scrubbed by a service manager; running as a user with no passwd entry.
Common situations: systemd unit missing Environment=HOME=...; Docker image without HOME; CI runners that clear the environment.
Related errors
- resolve task-local CLI config root: %w
- open %s %s: %w
- %s %q uses unsupported ~user expansion
- read config.toml: %w
- write config.toml: %w
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/f7d0b2444e44fd02.
Report an issue: GitHub.