chenhg5/cc-connect · error
codex: write config.toml: %w
Error message
codex: write config.toml: %w
What it means
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.
Source
Thrown at agent/codex/provider_config.go:35
return nil
}
home, err := resolveCodexHomeForConfig(codexHome)
if err != nil {
return fmt.Errorf("codex: resolve codex home: %w", err)
}
if err := os.MkdirAll(home, 0o755); err != nil {
return fmt.Errorf("codex: mkdir codex home: %w", err)
}
cfgPath := filepath.Join(home, "config.toml")
raw, _ := os.ReadFile(cfgPath)
content := string(raw)
section := buildProviderSection(name, baseURL, wireAPI, headers)
updated := upsertProviderSection(content, name, section)
if err := os.WriteFile(cfgPath, []byte(updated), 0o644); err != nil {
return fmt.Errorf("codex: write config.toml: %w", err)
}
slog.Debug("codex: wrote provider config", "provider", name, "path", cfgPath)
return nil
}
// ensureCodexAuth writes $CODEX_HOME/auth.json with the provider's API key,
// matching cc-switch's approach: {"OPENAI_API_KEY": "...", "auth_mode": "api_key"}.
// This is the standard way to authenticate Codex CLI with third-party providers.
func ensureCodexAuth(codexHome, apiKey string) error {
if apiKey == "" {
return nil
}
home, err := resolveCodexHomeForConfig(codexHome)
if err != nil {
return fmt.Errorf("codex: resolve codex home: %w", err)
}
if err := os.MkdirAll(home, 0o755); err != nil {
return fmt.Errorf("codex: mkdir codex home: %w", err)View on GitHub (pinned to 4000b2338a)
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.
Example fix
// before -rw------- root root ~/.codex/config.toml # cc-connect runs as alice // after sudo chown alice:alice ~/.codex/config.toml && chmod 644 ~/.codex/config.toml
Defensive patterns
Strategy: validation
Validate before calling
cfgPath := filepath.Join(codexHome, "config.toml")
if fi, err := os.Stat(cfgPath); err == nil && (fi.IsDir() || fi.Mode().Perm()&0o200 == 0) {
return fmt.Errorf("%s is not writable", cfgPath)
}
// also confirm the file is writable by opening for append
f, err := os.OpenFile(cfgPath, os.O_WRONLY|os.O_CREATE, 0o644)
if err != nil { return fmt.Errorf("config.toml not writable: %w", err) }
f.Close() Try / catch
if err := ensureCodexProviderConfig(home, name, baseURL, wireAPI, headers); err != nil {
if strings.Contains(err.Error(), "write config.toml") {
return fmt.Errorf("check ownership/permissions of %s/config.toml: %w", home, err)
}
return err
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- codex: mkdir codex home: %w
- work_dir is not accessible: %s: %w
- write task script: %w
- read existing Agy hooks %s: %w
- write Agy hooks overlay: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/f982f80780b2c709.
Report an issue: GitHub.