Skip to content

Bulk upload from a hasMany upload field: closing the drawer once without uploading silently drops the next upload (docs created, field unchanged) #18652

Open

Description

@alaintammermann-dot

Describe the Bug

In a hasMany upload field, open the bulk upload drawer with "Create New", close it without uploading (X → "Leave anyway", click outside, or Escape), then open it again and upload files. The documents are created on the server, the toast says "Successfully saved N files", the drawer closes — but the field value is not updated: nothing is added to the list. Reloading the page restores the normal behaviour.

Cause (read in @payloadcms/ui 3.90.2 dist and in main):

  • elements/BulkUpload/index.tsx — in the onModalStateChanged effect, every close of the drawer resets the success callback to a no-op (setOnSuccess(() => () => null)).
  • fields/Upload/Input.tsx — onLocalFileSelection opens the drawer without re-registering the callback; it is only (re)registered by useEffect(() => { setOnSuccess(onUploadSuccess) }, [value, path, onUploadSuccess, setOnSuccess]), and onUploadSuccess is memoized on [value, …]. After a close with no upload, the value has not changed, so the callback stays a no-op for the rest of the page session.

Related: #17560 (proposes registering the callback at open time, which would also cover this case).

Suggested fix: in onLocalFileSelection, call setOnSuccess(onUploadSuccess) right before openModal(drawerSlug) (and add both to the dependency array) — or stop resetting the callback on close, since each upload field has its own BulkUploadProvider.

Link to the code that reproduces this issue

Reproduces with the stock hasMany upload field, no custom code: any collection with { name: 'photos', type: 'upload', relationTo: 'media', hasMany: true }.

Reproduction Steps

  1. Edit a document that has a hasMany upload field.
  2. Click "Create New" in the field → the bulk upload drawer opens.
  3. Close it without adding files (X, or click the dimmed background).
  4. Click "Create New" again, add 2 files, click "Save".
  5. Toast "Successfully saved 2 files", drawer closes.
  6. Expected: the 2 new documents appear in the field list (unsaved). Actual: the list is unchanged; the documents exist in the collection.
  7. Reload the page and repeat steps 4–5 without step 3: works.

Which area(s) are affected?

area: ui

Environment Info

  • Payload 3.90.2, @payloadcms/ui 3.90.2, @payloadcms/db-postgres 3.90.2
  • Next.js 16.3.8, React 19.3.0, Node 24
  • Browsers: Safari iOS 26 and Chrome 142 (desktop)

Activity

  1. Metehan-Bicer commented on Oct 10, 2026

    @Metehan-Bicer

    Hi! I'd like to take this one.

    Your diagnosis matches what I see on main: BulkUpload/index.tsx resets the success callback on every close, and Upload/Input.tsx only registers it again from an effect keyed on value, so after a close with no upload it stays a no-op.

    Plan: register onUploadSuccess in onLocalFileSelection right before openModal(drawerSlug) (the narrower of your two options), with an e2e case in test/uploads/e2e.spec.ts: open the bulk upload drawer, close it, reopen it, upload, and expect the file in the field. #17560 touches the same callback but has been idle since July; this would be a narrow fix for this case only. I'll target main and can do a 3.x backport if that helps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions