router-for-me/CLIProxyAPI · error
failed to write file: %w
Error message
failed to write file: %w
What it means
writeAuthFile in auth_files_crud.go persists an uploaded auth file with os.WriteFile(dst, data, 0o600) after building the Auth record. If the OS write to auths/<name> fails, it wraps as `failed to write file: %w`. The destination is constrained to h.cfg.AuthDir with a basename, so path traversal is already excluded — this is an environment-level write failure.
Source
Thrown at internal/api/handlers/management/auth_files_crud.go:273
if err := h.writeAuthFile(ctx, name, data); err != nil {
return "", err
}
return name, nil
}
func (h *Handler) writeAuthFile(ctx context.Context, name string, data []byte) error {
dst := filepath.Join(h.cfg.AuthDir, filepath.Base(name))
if !filepath.IsAbs(dst) {
if abs, errAbs := filepath.Abs(dst); errAbs == nil {
dst = abs
}
}
auth, err := h.buildAuthFromFileData(dst, data)
if err != nil {
return err
}
if errWrite := os.WriteFile(dst, data, 0o600); errWrite != nil {
return fmt.Errorf("failed to write file: %w", errWrite)
}
if err := h.upsertAuthRecord(ctx, auth); err != nil {
return err
}
return nil
}
func requestedAuthFileNamesForDelete(c *gin.Context) ([]string, error) {
if c == nil {
return nil, nil
}
names := uniqueAuthFileNames(c.QueryArray("name"))
if len(names) > 0 {
return names, nil
}
body, err := io.ReadAll(c.Request.Body)
if err != nil {View on GitHub (pinned to 78f0c4079e)
Solutions
- Ensure the configured authDir exists and is writable by the proxy process user (mkdir -p auths && chown).
- Check disk space and quotas on the authDir filesystem.
- On containers, mount auths/ as a writable volume with correct ownership.
- Read the wrapped OS error for the precise errno (permission, ENOSPC, EROFS) and address that.
Example fix
# before $ docker run -v ./auths:/app/auths:ro ... # read-only mount # after $ docker run -v ./auths:/app/auths ... # writable mount $ chown -R 1000:1000 ./auths
Defensive patterns
Strategy: validation
Validate before calling
func authDirWritableForWrite(authDir string) bool {
if err := os.MkdirAll(authDir, 0o755); err != nil { return false }
probe := filepath.Join(authDir, ".probe")
ok := os.WriteFile(probe, nil, 0o600) == nil
_ = os.Remove(probe)
return ok
} Type guard
func isAuthFileWriteFailure(err error) bool {
return err != nil && strings.Contains(err.Error(), "failed to write file")
} Prevention
- Pre-flight check write access to authDir before enabling uploads.
- Mount auths/ writable and owned by the process user in containers.
- Monitor disk space on the authDir filesystem.
When it happens
Trigger: authDir does not exist; directory or existing file not writable by the process user; disk full; SELinux denial; container read-only volume; existing file owned by root with 0600 while proxy runs unprivileged.
Common situations: Docker deployments mounting auths/ read-only or as root-owned volume; first run before authDir was created; disk quota exhausted; permission mismatch after migrating hosts.
Related errors
- failed to remove file: %w
- no file uploaded
- failed to open uploaded file: %w
- failed to read uploaded file: %w
- auth path is empty
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/7cd65f750daa7990.
Report an issue: GitHub.