router-for-me/CLIProxyAPI · error
failed to remove file: %w
Error message
failed to remove file: %w
What it means
deleteAuthFileByName removes the target file from disk with os.Remove after resolving it under authDir (or the auth record's stored `path`). If Remove fails and it is not a not-exist case (which maps to 404 errAuthFileNotFound), the error wraps as `failed to remove file: %w` with HTTP 500. Causes are environmental: permission denied on file/dir, read-only filesystem, or the file being a non-empty directory.
Source
Thrown at internal/api/handlers/management/auth_files_crud.go:368
if targetAuth := h.findAuthForDelete(name); targetAuth != nil {
if !isPluginVirtualSourceDelete(name, targetAuth) {
return filepath.Base(name), http.StatusConflict, errPluginVirtualAuth
}
targetID = strings.TrimSpace(targetAuth.ID)
if path := strings.TrimSpace(authAttribute(targetAuth, "path")); path != "" {
targetPath = path
}
}
if !filepath.IsAbs(targetPath) {
if abs, errAbs := filepath.Abs(targetPath); errAbs == nil {
targetPath = abs
}
}
if errRemove := os.Remove(targetPath); errRemove != nil {
if os.IsNotExist(errRemove) {
return filepath.Base(name), http.StatusNotFound, errAuthFileNotFound
}
return filepath.Base(name), http.StatusInternalServerError, fmt.Errorf("failed to remove file: %w", errRemove)
}
if errDeleteRecord := h.deleteTokenRecord(ctx, targetPath); errDeleteRecord != nil {
return filepath.Base(name), http.StatusInternalServerError, errDeleteRecord
}
h.removeAuthsForPath(ctx, targetPath, targetID)
return filepath.Base(name), http.StatusOK, nil
}
func isPluginVirtualSourceDelete(name string, auth *coreauth.Auth) bool {
if !coreauth.IsPluginVirtualAuth(auth) {
return true
}
sourcePath := strings.TrimSpace(authAttribute(auth, coreauth.AttributeVirtualSource))
if sourcePath == "" {
sourcePath = strings.TrimSpace(authAttribute(auth, "path"))
}
if sourcePath == "" {
return falseView on GitHub (pinned to 78f0c4079e)
Solutions
- Read the wrapped OS error: EACCES -> fix ownership/permissions of the file and authDir; EROFS -> remount volume writable.
- In containers, mount auths/ writable and owned by the process user.
- Verify the auth record's `path` attribute points to a location the proxy may delete.
- Retry after fixing permissions — the record cleanup (deleteTokenRecord, removeAuthsForPath) runs only after successful removal.
Example fix
# before: root-owned auth file, proxy runs as app user $ ls -l auths/x.json # -rw------- root root # after $ chown $(id -u app):$(id -g app) auths/x.json && chmod u+rw auths/x.json
Defensive patterns
Strategy: validation
Validate before calling
func canDeleteAuthFile(path string) bool {
info, err := os.Stat(path)
if err != nil { return false }
// writable check: try opening for write
f, err := os.OpenFile(path, os.O_WRONLY, 0o600)
if err != nil { return false }
_ = f.Close()
return true
} Type guard
func isRemoveFailure(err error) bool {
return err != nil && strings.Contains(err.Error(), "failed to remove file")
} Prevention
- Ensure the process user owns/writes both the auth files and authDir.
- Mount auths/ writable in containers.
- Verify auth record `path` attributes point to deletable locations.
When it happens
Trigger: authDir file owned by root while the proxy runs unprivileged; auths/ mounted read-only in a container; file has immutable attribute; targetPath resolved from the auth record's `path` attribute points somewhere the process cannot write; attempting to remove a directory with entries.
Common situations: Docker auths volumes owned by root; SELinux/AppArmor policies; files created by a previous run under a different user; NFS mounts with root_squash.
Related errors
- failed to write file: %w
- failed to read auth file: %w
- failed to update source auth file: %w
- failed to create directory: %v
- failed to create token file: %w
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/3393227ab03340b7.
Report an issue: GitHub.