pocketbase/pocketbase · error

failed to upload all files: %w

Error message

failed to upload all files: %w

What it means

Aggregate error returned when a file upload fails: joins the per-file upload error (126), plus any cleanup error from deleting already-uploaded files. It means the whole upload was aborted and best-effort rollback of partially written files was attempted; if cleanup also failed, that error is in the join too, and orphaned files may remain in storage.

Source

Thrown at core/field_file.go:548

	var succeeded []string // list of uploaded file names

	for _, upload := range uploads {
		path := record.BaseFilesPath() + "/" + upload.Name
		if err := fsys.UploadFile(upload, path); err == nil {
			succeeded = append(succeeded, upload.Name)
		} else {
			failed = append(failed, fmt.Errorf("%q: %w", upload.Name, err))
			break // for now stop on the first error since we currently don't allow partial uploads
		}
	}

	if len(failed) > 0 {
		// cleanup - try to delete the successfully uploaded files (if any)
		_, cleanupErr := f.deleteFilesByNamesList(newContextIfInvalid(ctx), app, record, succeeded)

		failed = append(failed, cleanupErr)

		return fmt.Errorf("failed to upload all files: %w", errors.Join(failed...))
	}

	return nil
}

func (f *FileField) deleteNewlyUploadedFiles(ctx context.Context, app App, record *Record) ([]string, error) {
	uploaded, _ := record.GetRaw(uploadedFilesPrefix + f.Name).([]*filesystem.File)
	if len(uploaded) == 0 {
		return nil, nil
	}

	names := make([]string, len(uploaded))
	for i, file := range uploaded {
		names[i] = file.Name
	}

	failed, err := f.deleteFilesByNamesList(ctx, app, record, list.ToUniqueStringSlice(names))
	if err != nil {

View on GitHub (pinned to 5d217ddb50)

Solutions

  1. Unwrap with errors.Unwrap/errors.Is on the joined error to separate upload failure from cleanup failure.
  2. Fix the primary upload cause first (see 126).
  3. If cleanupErr is non-nil, scan the record's storage folder (pb_data/storage/<collectionId>/<recordId>/) for orphans and delete them manually.
  4. Retry the request after fixing storage; nothing was persisted for this upload.
Defensive patterns

Strategy: retry

Try / catch

err := app.Save(record)
if err != nil {
    var joined interface{ Unwrap() []error }
    if errors.As(err, &joined) {
        for _, e := range joined {
            // separate upload failure from cleanup failure and act accordingly
        }
    }
}

Prevention

When it happens

Trigger: Any record create/update with file uploads where at least one UploadFile fails. The pattern is: upload files in order, stop at first error, delete the succeeded ones, then return errors.Join(uploadErr, cleanupErr).

Common situations: Same as 126 (permissions, disk full, S3 issues), plus orphaned-file residue when the cleanup delete also fails — e.g. disk full prevented both the upload and the cleanup, or the context was cancelled (code swaps in a fresh Background context for cleanup to mitigate this).

Related errors


AI-assisted analysis of pocketbase/pocketbase@5d217ddb50 (2026-08-15). Data as JSON: /api/errors/8f8c690492558a0f. Report an issue: GitHub.