{"record":{"id":"6e7633a89a5b83ba","repo":"chenhg5/cc-connect","slug":"codex-mkdir-codex-home-w","errorCode":null,"errorMessage":"codex: mkdir codex home: %w","messagePattern":"codex: mkdir codex home: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/codex/provider_config.go","lineNumber":24,"sourceCode":"\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}\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\"}.","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/agent/codex/provider_config.go#L6-L42","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nEnvironment=CODEX_HOME=/mnt/ro/codex  # read-only mount\n// after\nEnvironment=CODEX_HOME=/home/alice/.codex  # writable","handlingStrategy":"validation","validationCode":"home := os.Getenv(\"CODEX_HOME\")\nif home == \"\" { h, _ := os.UserHomeDir(); home = filepath.Join(h, \".codex\") }\nif fi, err := os.Stat(home); err == nil && !fi.IsDir() {\n    return fmt.Errorf(\"CODEX_HOME %s is a file, not a directory\", home)\n}\nif err := os.MkdirAll(home, 0o755); err != nil {\n    return fmt.Errorf(\"cannot create codex home %s: %w\", home, err)\n}","typeGuard":null,"tryCatchPattern":"if err := ensureCodexProviderConfig(home, name, baseURL, wireAPI, headers); err != nil {\n    var pe *fs.PathError\n    if errors.As(err, &pe) && errors.Is(pe.Err, syscall.EACCES) {\n        return fmt.Errorf(\"fix permissions on %s: %w\", home, err)\n    }\n    return err\n}","preventionTips":["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."],"tags":["filesystem","mkdir","permissions","config"],"backgroundTag":"mkdir-permission-denied","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"}