router-for-me/CLIProxyAPI · error
failed to create directory: %v
Error message
failed to create directory: %v
What it means
os.MkdirAll failed creating the parent directory of the auth file path (default under auths/) with mode 0700. The error message uses %v rather than %w, so the cause is embedded as text, not wrapped. Typical causes are permission denied on the parent, a read-only filesystem, or a path segment that exists as a regular file.
Source
Thrown at internal/auth/codex/token.go:61
func (ts *CodexTokenStorage) SetMetadata(meta map[string]any) {
ts.Metadata = meta
}
// SaveTokenToFile serializes the Codex token storage to a JSON file.
// This method creates the necessary directory structure and writes the token
// data in JSON format to the specified file path for persistent storage.
// It merges any injected metadata into the top-level JSON object.
//
// Parameters:
// - authFilePath: The full path where the token file should be saved
//
// Returns:
// - error: An error if the operation fails, nil otherwise
func (ts *CodexTokenStorage) SaveTokenToFile(authFilePath string) error {
misc.LogSavingCredentials(authFilePath)
ts.Type = "codex"
if err := os.MkdirAll(filepath.Dir(authFilePath), 0700); err != nil {
return fmt.Errorf("failed to create directory: %v", err)
}
// Merge metadata using helper
data, errMerge := misc.MergeMetadata(ts, ts.Metadata)
if errMerge != nil {
return fmt.Errorf("failed to merge metadata: %w", errMerge)
}
f, err := os.Create(authFilePath)
if err != nil {
return fmt.Errorf("failed to create token file: %w", err)
}
defer func() {
if errClose := f.Close(); errClose != nil {
log.Errorf("codex token storage: close token file error: %v", errClose)
}
}()
View on GitHub (pinned to 78f0c4079e)
Solutions
- Check the path in the log line (LogSavingCredentials prints it) and inspect parent permissions: `ls -ld <dir>`.
- Pre-create the directory with correct ownership: `mkdir -p <auth-dir> && chown $(id -u) <auth-dir>`.
- Fix volume mounts to be rw, or point auth-dir at a writable location.
- Remove any regular file occupying a needed directory component.
- Run the process as a user permitted to write the auth directory.
Example fix
# before: auth-dir: /var/lib/cliproxy/auths (root-owned, process unprivileged) # after sudo mkdir -p /var/lib/cliproxy/auths && sudo chown $(whoami) /var/lib/cliproxy/auths
Defensive patterns
Strategy: validation
Validate before calling
// Ensure the auth directory exists and is writable before starting the flow
info, err := os.Stat(authDir)
if os.IsNotExist(err) {
if err := os.MkdirAll(authDir, 0o700); err != nil { return err }
} else if err != nil {
return err
} else if !info.IsDir() {
return fmt.Errorf("%s exists but is a file", authDir)
} Try / catch
if err := ts.SaveTokenToFile(path); err != nil {
if strings.Contains(err.Error(), "failed to create directory") {
// fix permissions/ownership of the parent dir, then retry the save
}
} Prevention
- Pre-create and chown the auth directory as part of deployment.
- Mount auth volumes read-write, never read-only.
- Smoke-test file creation in the auth dir at startup.
When it happens
Trigger: Running the process as a user without write access to the configured auth-dir; auths path configured inside a read-only volume/mount; a file exists where a directory component is needed (e.g. ./auths is a file); disk/inode exhaustion in rare cases.
Common situations: Running in Docker with an incorrectly mounted volume (read-only); config.yaml auth-dir pointing at a root-owned path while the server runs unprivileged; leftover file blocking directory creation after config change.
Related errors
- failed to create token file: %w
- failed to save refreshed auth: %w
- failed to create directory: %v
- failed to create token file: %w
- failed to write token to file: %w
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/4c2ab554dff7f454.
Report an issue: GitHub.