Skip to content

Lost batch-mutation responses cannot repair persisted workspace references: needs server-side outcome reconciliation #9533

Description

@lstein

Summary

When a batch image mutation's response is lost to a transport-shaped failure (timeout, network drop, parsing error, 5xx), the client cannot know which names committed. Since #9394 it reports those names as failed while invalidating their caches as if the chunk had landed, so RTK-cached views reconcile on refetch — but persisted workspace references do not: handleDeletions strips deleted images out of canvas layers, nodes, and reference images only off a deleted_images payload, and a lost response has none. Effect: a delete that committed server-side can leave persisted slices pointing at gone images until the user notices 404s.

Why the client cannot reconcile this alone

The obvious client-side move — probe the failing chunk's names via POST /api/v1/images/images_by_names and treat absent names as confirmed-deleted — is unsafe with that route's current semantics: it answers per-name authorization failures and per-name storage errors with a silent skip (invokeai/app/api/routers/images.py, get_images_by_names). A locked database therefore returns 200 [], which would "confirm" every probed name as deleted and mass-prune workspace references for images that all still exist. Absence from that response is not evidence of deletion.

Proposed fix (server-side)

Either of:

  1. Tri-state existence reconciliation: a route taking image_names and answering per name existing / gone / undecided, where gone is asserted only on a positive ImageRecordNotFoundException read, storage errors answer undecided, and names the caller may not read answer undecided (no information leak). The client then moves gone names into deleted_images (running the normal deletion cleanup), keeps existing names failed (retry works), and leaves undecided names failed without cleanup. A fully unavailable database yields all-undecided and prunes nothing.
  2. Per-operation ids on the batch mutations plus an outcome endpoint, as suggested in review — heavier, but also covers non-delete mutations and retry dedup.

Context

Raised by @JPPhoto in review of #9394 (round of 2026-08-23: "Lost mutation responses leave stale local references... Recovery: add mutation ids and server-side outcome reconciliation"). #9394 ships the cache-invalidation half; this issue tracks the workspace-reference half, which needs a server-side source of truth. Related: #9531 (bulk-download replay after re-auth).

Activity

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions