chenhg5/cc-connect · error
codex: mkdir codex home: %w
Error message
codex: mkdir codex home: %w
What it means
After resolving the codex home, ensureCodexProviderConfig calls os.MkdirAll(home, 0o755) to guarantee the directory exists before writing config.toml. If directory creation fails, this error wraps the OS reason. It indicates the codex home directory could not be created (permissions, path conflicts, read-only filesystem).
Source
Thrown at agent/codex/provider_config.go:24
"log/slog"
"os"
"path/filepath"
"strings"
)
// ensureCodexProviderConfig writes or updates a [model_providers.<name>] section
// in $CODEX_HOME/config.toml so that Codex CLI can use the provider's wire_api
// and http_headers settings.
func ensureCodexProviderConfig(codexHome, name, baseURL, wireAPI string, headers map[string]string) error {
if name == "" {
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"}.View on GitHub (pinned to 4000b2338a)
Solutions
- Check the wrapped OS error: if permission denied, chown/chmod the parent directory or run as the correct user.
- Verify CODEX_HOME is a valid directory path, not an existing regular file.
- Ensure the filesystem containing CODEX_HOME is writable and not full.
- Pre-create the directory manually: mkdir -p ~/.codex.
Example fix
// before Environment=CODEX_HOME=/mnt/ro/codex # read-only mount // after Environment=CODEX_HOME=/home/alice/.codex # writable
Defensive patterns
Strategy: validation
Validate before calling
home := os.Getenv("CODEX_HOME")
if home == "" { h, _ := os.UserHomeDir(); home = filepath.Join(h, ".codex") }
if fi, err := os.Stat(home); err == nil && !fi.IsDir() {
return fmt.Errorf("CODEX_HOME %s is a file, not a directory", home)
}
if err := os.MkdirAll(home, 0o755); err != nil {
return fmt.Errorf("cannot create codex home %s: %w", home, err)
} Try / catch
if err := ensureCodexProviderConfig(home, name, baseURL, wireAPI, headers); err != nil {
var pe *fs.PathError
if errors.As(err, &pe) && errors.Is(pe.Err, syscall.EACCES) {
return fmt.Errorf("fix permissions on %s: %w", home, err)
}
return err
} Prevention
- Ensure CODEX_HOME points to a writable directory owned by the service user.
- Never point CODEX_HOME at read-only mounts or an existing regular file.
- Pre-create ~/.codex during provisioning.
- Monitor disk space/quota on the volume hosting CODEX_HOME.
When it happens
Trigger: os.MkdirAll(home, 0o755) returns an error — parent directories not writable, a file exists at the home path, disk full, or the path is on a read-only mount — during StartSession provider setup or the corresponding tests.
Common situations: CODEX_HOME pointing at a read-only or nonexistent mount; permission-denied creating ~/.codex (restricted home dir); a regular file already exists at the CODEX_HOME path; running as a different user than expected in a container.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- codex: write config.toml: %w
- cannot create config directory: %w
- cannot create config directory: %w
- work_dir is not accessible: %s: %w
- create data dir: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/6e7633a89a5b83ba.
Report an issue: GitHub.