{"record":{"id":"f982f80780b2c709","repo":"chenhg5/cc-connect","slug":"codex-write-config-toml-w","errorCode":null,"errorMessage":"codex: write config.toml: %w","messagePattern":"codex: write config\\.toml: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/codex/provider_config.go","lineNumber":35,"sourceCode":"\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}\n\n// ensureCodexAuth writes $CODEX_HOME/auth.json with the provider's API key,\n// matching cc-switch's approach: {\"OPENAI_API_KEY\": \"...\", \"auth_mode\": \"api_key\"}.\n// This is the standard way to authenticate Codex CLI with third-party providers.\nfunc ensureCodexAuth(codexHome, apiKey string) error {\n\tif apiKey == \"\" {\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)","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/agent/codex/provider_config.go#L17-L53","documentation":"ensureCodexProviderConfig builds the updated provider section, upserts it into the existing config.toml content, and persists it with os.WriteFile(cfgPath, ..., 0o644). If the write fails, this error wraps the OS reason. The provider configuration was computed but could not be saved.","triggerScenarios":"os.WriteFile on $CODEX_HOME/config.toml fails — permission denied on the file/dir, config.toml exists as a directory or read-only file, disk full, or the path was deleted between read and write — during StartSession provider setup.","commonSituations":"config.toml owned by root while cc-connect runs as another user; CODEX_HOME on a read-only volume; immutable/locked file (Windows AV lock); disk quota exceeded; tests using temp dirs that were cleaned up.","solutions":["Inspect the wrapped OS error; fix permissions on CODEX_HOME/config.toml (chown/chmod 0o644 writable by the process user).","Ensure config.toml is a regular file, not a directory or read-only file.","Check disk space/quota on the volume holding CODEX_HOME.","Set CODEX_HOME to a writable location the cc-connect process user owns."],"exampleFix":"// before\n-rw------- root root ~/.codex/config.toml  # cc-connect runs as alice\n// after\nsudo chown alice:alice ~/.codex/config.toml && chmod 644 ~/.codex/config.toml","handlingStrategy":"validation","validationCode":"cfgPath := filepath.Join(codexHome, \"config.toml\")\nif fi, err := os.Stat(cfgPath); err == nil && (fi.IsDir() || fi.Mode().Perm()&0o200 == 0) {\n    return fmt.Errorf(\"%s is not writable\", cfgPath)\n}\n// also confirm the file is writable by opening for append\nf, err := os.OpenFile(cfgPath, os.O_WRONLY|os.O_CREATE, 0o644)\nif err != nil { return fmt.Errorf(\"config.toml not writable: %w\", err) }\nf.Close()","typeGuard":null,"tryCatchPattern":"if err := ensureCodexProviderConfig(home, name, baseURL, wireAPI, headers); err != nil {\n    if strings.Contains(err.Error(), \"write config.toml\") {\n        return fmt.Errorf(\"check ownership/permissions of %s/config.toml: %w\", home, err)\n    }\n    return err\n}","preventionTips":["Ensure config.toml is writable by the cc-connect process user (chown/chmod after manual edits as root).","Never place config.toml on read-only or quota-limited volumes.","Confirm config.toml is a regular file, not a directory.","Re-check permissions after administrative edits or migrations."],"tags":["filesystem","config","file-write","permissions"],"backgroundTag":"file-write-failed","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"}