router-for-me/CLIProxyAPI · error
failed to create token file: %w
Error message
failed to create token file: %w
What it means
os.Create on the auth file path failed after the directory was successfully created. The token is not persisted, so a successful OAuth login is lost on restart. The wrapped error distinguishes permission issues from path problems (name too long, is-a-directory, O_RDONLY filesystem).
Source
Thrown at internal/auth/claude/token.go:91
func (ts *ClaudeTokenStorage) SaveTokenToFile(authFilePath string) error {
misc.LogSavingCredentials(authFilePath)
ts.Type = "claude"
// Create directory structure if it doesn't exist
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)
}
// Create the token file
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("claude token storage: close token file error: %v", errClose)
}
}()
// Encode and write the token data as JSON
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
- Check the wrapped error text and fix the specific cause: chmod the directory (needs w+x for the runtime user) or remove the conflicting directory at the file path.
- Confirm the auth-dir volume is mounted read-write in containers.
- Verify the full resolved path is a file location, not a directory.
Example fix
# before chmod 111 auths # traverse-only: mkdir check passes, file create fails # after chmod 700 auths && chown appuser auths
Defensive patterns
Strategy: validation
Validate before calling
if info, err := os.Stat(authFilePath); err == nil && info.IsDir() {
return errors.New("auth file path is a directory")
}
f, err := os.OpenFile(authFilePath, os.O_WRONLY|os.O_CREATE, 0600)
if err != nil { return fmt.Errorf("cannot write auth file: %w", err) }
f.Close() Try / catch
if err := storage.SaveTokenToFile(path); err != nil && strings.Contains(err.Error(), "failed to create token file") {
log.Errorf("check permissions on %s", filepath.Dir(path))
} Prevention
- Give the runtime user write+execute on auth-dir (chmod 700).
- Startup smoke-test: touch a file in auth-dir before doing any login.
When it happens
Trigger: The directory exists and is writable enough for MkdirAll to succeed, but creating the file itself fails: directory without write permission for the file (execute-only traversal), the target path is itself a directory, read-only mount, or filename constraints exceeded.
Common situations: auth-dir with mode that allows mkdir traversal but not file creation; auth file path accidentally set to an existing directory; read-only container filesystems where MkdirAll no-ops on existing dirs but Create fails; path length limits with deeply nested auth-dirs.
Related errors
- failed to create directory: %v
- failed to write token to file: %w
- failed to create directory: %v
- failed to create token file: %w
- failed to save refreshed auth: %w
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/7d38b59708e83583.
Report an issue: GitHub.