Skip to content

fix: stop a half-completed media collection move reporting success (#6017) - #6123

Merged
atomantic merged 1 commit into
mainfrom
claim/issue-6017
Sep 3, 2026
Merged

fix: stop a half-completed media collection move reporting success (#6017)#6123
atomantic merged 1 commit into
mainfrom
claim/issue-6017

Conversation

@atomantic

Copy link
Copy Markdown
Owner

Summary

Moving items between media collections is two writes: add to the target, then remove from the source. bulkMoveOrCopy in client/src/pages/MediaCollectionDetail.jsx swallowed every removal error into null (.catch(() => null)) and computed its failure count as selectedItems.length - added - dupes — which only accounts for add failures. A move whose removals all failed still toasted Moved N to "…" while the items sat duplicated in both collections, and exitSelectMode() cleared the selection so the user had nothing left to retry.

This change:

  • Tracks the keys whose removal failed in a removeFailedKeys set, separate from the add-failure count.
  • Never toasts success when a removal failed. The message is Copied N to "<target>", but M could not be removed from "<source>" — deliberately "Copied", because calling a half-completed move a "Move" is exactly the false success this branch exists to prevent. An add failure appends ; K failed to add to the same message.
  • Still reconciles collection to the authoritative server state returned by the last successful removal, so a partial failure doesn't leave the view showing items that did move out.
  • Keeps select mode open with only the half-moved items selected, so the move (or a plain Remove) can be re-run on exactly what failed.

The synthetic Unsorted source is unaffected — it never issues removals, it just re-derives via refresh().

Rejected alternative (per the issue): rolling back the adds in the target collection with automated DELETEs. Accurate partial-progress reporting leaves the user in control instead of cascading more writes onto an already-unstable destination.

Test plan

  • client/src/pages/MediaCollectionDetail.test.jsx gains three cases covering bulkMoveOrCopy: every removal succeeds (plain success toast, select mode exits), every removal fails (error toast, no success toast, all items stay selected), and a mixed run where one add and one removal fail (both counts reported, collection reconciled to the last successful removal, selection narrowed to the one failed key). BulkTargetPicker is now mocked with a clickable destination row so the flow can be driven end to end.
  • Verified the two failure-path tests fail against the pre-fix component and pass after it.
  • cd client && npx vitest run — 832 files / 10220 tests pass. One unrelated pre-existing date-boundary flake in src/components/calendar/ReviewTab.test.jsx failed on the first run and passed on re-run; it is untouched by this diff.

Closes #6017

https://claude.ai/code/session_01VjkWVTfzKyRuAv3HEsspwN

…6017)

Moving items between media collections is two writes: add to the target,
then remove from the source. bulkMoveOrCopy swallowed every removal error
into null and only counted add failures, so a move whose removals all
failed still toasted "Moved N to ..." while the items sat duplicated in
both collections — and clearing the selection left the user with nothing
to retry.

Removal failures are now tracked separately. When any removal fails the
toast says "Copied N ..., but M could not be removed from ..." (never a
success toast), the collection still reconciles to the authoritative
server state from the last successful removal, and select mode stays open
with only the half-moved items selected so the move can be re-run on
exactly what failed. Add failures keep their own count in the same
message.

Claude-Session: https://claude.ai/code/session_01VjkWVTfzKyRuAv3HEsspwN
@atomantic
atomantic merged commit 9d6702e into main Sep 3, 2026
7 checks passed
@atomantic
atomantic deleted the claim/issue-6017 branch September 3, 2026 22:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MediaCollectionDetail: bulkMoveOrCopy swallows item removal failures during move, reporting false success and leaving duplicated items

1 participant