From 58c5e424d92c7b0b871b63b3d64eb7a5c20a05b6 Mon Sep 17 00:00:00 2001 From: Garret Patti <42485635+garretpatti@users.noreply.github.com> Date: Mon, 6 Apr 2026 18:59:51 -0400 Subject: [PATCH] Fix media_tags not updating when fingerprint move is detected MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit reKeyMediaItem was called with item_key values (e.g. "lib1:movie:Inception") but media_tags stores keys in the shorter UI format (e.g. "lib1:Inception"), so the UPDATE never matched any rows. Add itemKeyToMediaKey() to extract the terminal segment of an item_key and reconstruct the media_key format the UI uses: lib1:movie:Inception%20(2010) → lib1:Inception%20(2010) lib1:tv_episode:Show:Season1:ep.mkv → lib1:ep.mkv lib1:mixed_file:dir%2Ffile.mp4 → lib1:dir%2Ffile.mp4 Also skip the UPDATE when old and new media_keys are identical (e.g. a TV episode moved between seasons keeps the same filename-based media_key). Co-Authored-By: Claude Sonnet 4.6 --- src/lib/scanner.ts | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/lib/scanner.ts b/src/lib/scanner.ts index 64b45a0..6dc7ea2 100644 --- a/src/lib/scanner.ts +++ b/src/lib/scanner.ts @@ -531,6 +531,22 @@ function detectMoves( * Tags on deleted items are intentionally left as orphans — harmless and * recoverable if the file reappears. */ +/** + * Converts an item_key (used in media_items) to the media_key format used in + * media_tags. The UI constructs media_keys as `${libraryId}:${shortId}` where + * shortId is only the terminal path segment — e.g.: + * "lib1:movie:Inception%20(2010)" → "lib1:Inception%20(2010)" + * "lib1:tv_episode:Show:S1:ep.mkv" → "lib1:ep.mkv" + * "lib1:mixed_file:dir%2Ffile.mp4" → "lib1:dir%2Ffile.mp4" + */ +function itemKeyToMediaKey(itemKey: string): string { + const firstColon = itemKey.indexOf(':') + const lastColon = itemKey.lastIndexOf(':') + const libraryId = itemKey.slice(0, firstColon) + const shortId = itemKey.slice(lastColon + 1) + return `${libraryId}:${shortId}` +} + function reconcileAndPrune( db: Database.Database, libraryId: string, @@ -541,7 +557,12 @@ function reconcileAndPrune( for (const { oldKey, newKey } of moves) { renameItem.run(newKey, oldKey) - reKeyMediaItem(oldKey, newKey) + // Convert item_keys to the media_key format actually used in media_tags + const oldMediaKey = itemKeyToMediaKey(oldKey) + const newMediaKey = itemKeyToMediaKey(newKey) + if (oldMediaKey !== newMediaKey) { + reKeyMediaItem(oldMediaKey, newMediaKey) + } console.log(`[scanner] fingerprint match: renamed "${oldKey}" → "${newKey}"`) }