pocketbase/pocketbase · warning
file %d (%q): %w
Error message
file %d (%q): %w
What it means
Per-file failure entry when FileField deletes a record's files: fsys.Delete(path) failed with something other than filesystem.ErrNotFound. The error records the file's index in the record's filename list, the filename, and the wrapped storage error. These entries are accumulated (not returned immediately) and later joined into error 129.
Source
Thrown at core/field_file.go:606
return filenames, err
}
defer fsys.Close()
fsys.SetContext(ctx)
var failures []error
for i := len(filenames) - 1; i >= 0; i-- {
filename := filenames[i]
if filename == "" || strings.ContainsAny(filename, "/\\") {
continue // empty or not a plain filename
}
path := record.BaseFilesPath() + "/" + filename
err := fsys.Delete(path)
if err != nil && !errors.Is(err, filesystem.ErrNotFound) {
// store the delete error
failures = append(failures, fmt.Errorf("file %d (%q): %w", i, filename, err))
} else {
// remove the deleted file from the list
filenames = append(filenames[:i], filenames[i+1:]...)
// try to delete the related file thumbs (if any)
thumbsErr := fsys.DeletePrefix(record.BaseFilesPath() + "/thumbs_" + filename + "/")
if len(thumbsErr) > 0 {
app.Logger().Warn("Failed to delete file thumbs", "error", errors.Join(thumbsErr...))
}
}
}
if len(failures) > 0 {
return filenames, fmt.Errorf("failed to delete all files: %w", errors.Join(failures...))
}
return nil, nil
}View on GitHub (pinned to 5d217ddb50)
Solutions
- Check the wrapped error for the storage cause (permission, S3 access denied).
- For local storage, fix ownership/permissions on pb_data/storage recursively (chown -R appuser: pb_data).
- For S3, add s3:DeleteObject to the bucket policy for the configured credentials.
- Manually verify the file at pb_data/storage/<collection>/<record>/ exists if the error seems spurious.
Example fix
// before: running the server as root sometimes, creating root-owned uploads // after: always run under the same user and fix existing files // chown -R pbuser:pbuser pb_data
Defensive patterns
Strategy: fallback
Try / catch
_, err := field.DeleteFiles(ctx, app, record, names) // or record delete path
if err != nil {
// entries carry index+filename; treat non-fatal for record deletion flows,
// log and schedule a storage sweep instead of failing the delete
} Prevention
- Keep consistent ownership/permissions on pb_data/storage.
- Grant S3 identities s3:DeleteObject, not just Put/Get.
- Never manually move or rename storage subfolders.
When it happens
Trigger: Deleting a record (or removing files from a file field) where the underlying storage delete fails: permission denied on the local file, S3 delete error, or path issues. Only plain filenames without path separators are attempted; ErrNotFound is tolerated because the file may already be gone.
Common situations: pb_data/storage files owned by root after running under a different user; S3 bucket policy forbidding DeleteObject; a file lock on Windows; the record's storage folder having been manually moved or renamed.
Related errors
- failed to delete all files: %w
- %q: %w
- failed to upload all files: %w
- prefix mustn't be empty
- failed to delete superuser %q: %w
AI-assisted analysis of pocketbase/pocketbase@5d217ddb50 (2026-08-15).
Data as JSON: /api/errors/3b2c541000c49254.
Report an issue: GitHub.