{"record":{"id":"f7d0b2444e44fd02","repo":"multica-ai/multica","slug":"resolve-s-q-user-home-w","errorCode":null,"errorMessage":"resolve %s %q: user home: %w","messagePattern":"resolve (.+?) %q: user home: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/internal/daemon/execenv/codex_home.go","lineNumber":1222,"sourceCode":"\t\treturn fmt.Errorf(\"close codex models cache binding %s: %w\", path, err)\n\t}\n\treturn nil\n}\n\n// resolveCodexConfigPath maps a path-valued config.toml entry to its source\n// file on this host. key is the config key the path came from and only shapes\n// the diagnostics, so an operator reading a failure knows which setting to fix.\n// A relative path resolves against the shared Codex home — that is the\n// directory the config was copied from, and the base Codex itself would have\n// used before the per-task home relocated CODEX_HOME.\nfunc resolveCodexConfigPath(configPath, sharedHome, key string) (string, error) {\n\tif filepath.IsAbs(configPath) {\n\t\treturn filepath.Clean(configPath), nil\n\t}\n\tif strings.HasPrefix(configPath, \"~/\") || strings.HasPrefix(configPath, `~\\`) {\n\t\thome, err := os.UserHomeDir()\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"resolve %s %q: user home: %w\", key, configPath, err)\n\t\t}\n\t\treturn filepath.Join(home, configPath[2:]), nil\n\t}\n\tif strings.HasPrefix(configPath, \"~\") {\n\t\treturn \"\", fmt.Errorf(\"%s %q uses unsupported ~user expansion\", key, configPath)\n\t}\n\treturn filepath.Join(sharedHome, filepath.Clean(configPath)), nil\n}\n\nfunc exposeSharedCodexPluginCache(codexHome, sharedHome string) error {\n\tsrc := filepath.Join(sharedHome, \"plugins\", \"cache\")\n\tdst := filepath.Join(codexHome, \"plugins\", \"cache\")\n\tif err := os.MkdirAll(src, 0o755); err != nil {\n\t\treturn fmt.Errorf(\"create shared plugin cache dir: %w\", err)\n\t}\n\tif err := os.MkdirAll(filepath.Dir(dst), 0o755); err != nil {\n\t\treturn fmt.Errorf(\"create codex plugin dir: %w\", err)\n\t}","sourceCodeStart":1204,"sourceCodeEnd":1240,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/internal/daemon/execenv/codex_home.go#L1204-L1240","documentation":"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.","triggerScenarios":"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.","commonSituations":"systemd unit missing Environment=HOME=...; Docker image without HOME; CI runners that clear the environment.","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"],"exampleFix":"// before (config.toml)\nmodel_provider_file = \"~/codex/providers.json\"\n\n// after\nmodel_provider_file = \"/home/daemon/codex/providers.json\"","handlingStrategy":"validation","validationCode":"if os.UserHomeDir() != nil {\n\treturn fmt.Errorf(\"HOME unset; cannot resolve ~/ paths in codex config\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set HOME/USERPROFILE in the daemon service environment","Prefer absolute paths in daemon-consumed Codex config"],"tags":["environment","config","codex"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}