router-for-me/CLIProxyAPI · error

failed to create token file: %w

Error message

failed to create token file: %w

What it means

os.Create failed opening the auth file for writing after the directory was created successfully. Causes: permission denied inside an existing directory, the target path is itself a directory, a read-only filesystem, or OS-level open-file limits. Note os.Create truncates an existing file, so a locked file can also surface here on some platforms.

Source

Thrown at internal/auth/codex/token.go:72

//
// 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)
		}
	}()

	if err = json.NewEncoder(f).Encode(data); err != nil {
		return fmt.Errorf("failed to write token to file: %w", err)
	}
	return nil
}

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Manually test creation: `touch <auth-file-path>` as the same user — the OS error will name the real cause.
  2. Fix ownership/ACLs on the auth directory, or relocate auth-dir to a writable path.
  3. Remove the trailing slash / directory occupying the file path.
  4. For SELinux, adjust the label (`chcon -t container_file_t` or policy) or run with the proper context.
  5. On NFS root_squash mounts, ensure the UID maps to a writable identity.

Example fix

# before: auth-dir: /mnt/nfs/auths/  (root_squash denies app user)
# after: auth-dir: /var/lib/cliproxy/auths (local writable volume)
Defensive patterns

Strategy: validation

Validate before calling

// Verify the exact file path is creatable before the flow starts
f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o600)
if err != nil { return err }
_ = f.Close()

Try / catch

if err := ts.SaveTokenToFile(path); err != nil {
    if strings.Contains(err.Error(), "failed to create token file") {
        // permission/SELinux/path-is-dir: fix fs, then re-run save; token data is still in memory
    }
}

Prevention

When it happens

Trigger: auths directory writable-check passed at mkdir time but file creation denied (sticky bit, ACL); the configured auth file path points at an existing directory; disk mounted read-only between mkdir and create; SELinux denying file creation in the context.

Common situations: SELinux/AppArmor denials on containers; path configuration ending in a trailing slash making the target a directory; NFS volume with root_squash denying the app user.

Related errors


AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15). Data as JSON: /api/errors/8daec6226202f281. Report an issue: GitHub.