From e49b4f1133b0093fc8596ddd09b2977aab040a18 Mon Sep 17 00:00:00 2001 From: Guilhem Lemouel Date: Tue, 25 Aug 2026 18:11:29 +0200 Subject: [PATCH] fix: a refresh takes every field the fresh read decides MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `refreshBlanks` merged only `missing` out of the new scan, so the two fields added alongside it were left at whatever the row said before. Both reviewers found the same seam from opposite ends: a resource that had just become unreadable kept its old readable-looking row, and one that had come back stayed blocked until a reload. These fields describe what is at the path now, so the fresh read owns all of them — and the branch that marks a row done clears them, because a row that has left the blank list was read and is filled. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Xg8vXUuHCH3aRkf91sfxjx --- .../src/lib/components/ImportSetupStep.svelte | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/frontend/src/lib/components/ImportSetupStep.svelte b/frontend/src/lib/components/ImportSetupStep.svelte index ae22622bee..d9b8e22374 100644 --- a/frontend/src/lib/components/ImportSetupStep.svelte +++ b/frontend/src/lib/components/ImportSetupStep.svelte @@ -339,8 +339,29 @@ } blanks = blanks.map((b) => { const f = stillBlank.get(b.path) - if (f) return { ...b, missing: f.missing, done: false, justSaved: false } - return { ...b, missing: [], done: true, justSaved: !b.done } + // Every field the fresh read decides is taken from it, not merged selectively: these + // describe what is at the path *now*. Keeping a stale `unreadable` leaves a resource + // that has since come back blocked until a reload, and keeping a stale absence hides + // one that has just become unreadable. + if (f) { + return { + ...b, + missing: f.missing, + unreadable: f.unreadable, + occupiedBy: f.occupiedBy, + done: false, + justSaved: false + } + } + // Gone from the blank list entirely: it was read, and it is filled. + return { + ...b, + missing: [], + unreadable: undefined, + occupiedBy: undefined, + done: true, + justSaved: !b.done + } }) // The flash is a one-shot; clear it so a later refresh does not replay it. for (const b of blanks) {