{"record":{"id":"c905c18c00081c50","repo":"chenhg5/cc-connect","slug":"codex-resolve-codex-home-w","errorCode":null,"errorMessage":"codex: resolve codex home: %w","messagePattern":"codex: resolve codex home: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/codex/provider_config.go","lineNumber":21,"sourceCode":"import (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n)\n\n// ensureCodexProviderConfig writes or updates a [model_providers.<name>] section\n// in $CODEX_HOME/config.toml so that Codex CLI can use the provider's wire_api\n// and http_headers settings.\nfunc ensureCodexProviderConfig(codexHome, name, baseURL, wireAPI string, headers map[string]string) error {\n\tif name == \"\" {\n\t\treturn nil\n\t}\n\thome, err := resolveCodexHomeForConfig(codexHome)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"codex: resolve codex home: %w\", err)\n\t}\n\tif err := os.MkdirAll(home, 0o755); err != nil {\n\t\treturn fmt.Errorf(\"codex: mkdir codex home: %w\", err)\n\t}\n\n\tcfgPath := filepath.Join(home, \"config.toml\")\n\traw, _ := os.ReadFile(cfgPath)\n\tcontent := string(raw)\n\n\tsection := buildProviderSection(name, baseURL, wireAPI, headers)\n\tupdated := upsertProviderSection(content, name, section)\n\n\tif err := os.WriteFile(cfgPath, []byte(updated), 0o644); err != nil {\n\t\treturn fmt.Errorf(\"codex: write config.toml: %w\", err)\n\t}\n\tslog.Debug(\"codex: wrote provider config\", \"provider\", name, \"path\", cfgPath)\n\treturn nil\n}","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/agent/codex/provider_config.go#L3-L39","documentation":"ensureCodexProviderConfig writes provider settings into $CODEX_HOME/config.toml. It first resolves the codex home via resolveCodexHomeForConfig (explicit codexHome arg, else CODEX_HOME/user home). If that resolution fails, the error is wrapped with this prefix. Without a home directory the provider config cannot be located or created.","triggerScenarios":"StartSession with a configured provider name while resolveCodexHomeForConfig fails — i.e. no explicit codexHome in agent opts, CODEX_HOME unset, and os.UserHomeDir() errors (HOME missing).","commonSituations":"Daemon/service environments without HOME; containers running as a non-login user; misconfigured unit files that scrub the environment; Windows services without a user profile loaded.","solutions":["Set CODEX_HOME to an absolute writable path in the environment.","Set HOME (or ensure the Windows user profile loads) so os.UserHomeDir succeeds.","Pass an explicit codexHome via agent options so resolution never depends on the environment.","Check the wrapped inner error (%w) for the precise UserHomeDir failure reason."],"exampleFix":"// before\nExecStart=/usr/local/bin/cc-connect  # HOME unset\n// after\n[Service]\nEnvironment=HOME=/home/alice\nEnvironment=CODEX_HOME=/home/alice/.codex","handlingStrategy":"validation","validationCode":"if os.Getenv(\"CODEX_HOME\") == \"\" {\n    if _, err := os.UserHomeDir(); err != nil {\n        return fmt.Errorf(\"set CODEX_HOME before starting codex with a provider: %w\", err)\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := ensureCodexProviderConfig(home, name, baseURL, wireAPI, headers); err != nil {\n    return fmt.Errorf(\"provider setup failed; is CODEX_HOME/HOME set? %w\", err)\n}","preventionTips":["Set CODEX_HOME explicitly wherever a provider is configured.","Pass codexHome through agent options rather than relying on env resolution.","Validate the service environment (HOME/CODEX_HOME) at daemon startup.","Test provider config under the same user that runs production."],"tags":["config","codex-home","provider","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"}