Skip to content

[bug] A tagged movie folder is merged into a different movie whose TMDB and IMDb IDs don't match its tags #2263

Open

Description

@amokster88

What happened

A movie folder tagged with its own TMDB and IMDb IDs gets attached to a different movie whose TMDB and IMDb IDs both differ from the tags. The tagged movie gets no catalog item (GET /api/v2/catalog/items/movie-tmdb-<tag> returns 404), and its file shows up as a second version of the other movie. For example, Batman (1943) is missing, and "Bataan (1943)" lists two versions, one of which is the Batman file.

Reproduced on demand, 1 of 1 attempt (2026-10-11, build 1258 · 3f171de). The AI agent named in the disclosure ran the admin API calls, with my approval. It detached the Batman file from "Bataan" without saving an override. The split's own rescan picked up the folder, and 27.7 s after the rescan row the server put the file back in "Bataan" and logged metadata: rebound skeleton to existing item. This ran on the state the first merge left behind; see Technical notes for why that matters.

First logged 2026-10-10, same build. A scan of library "Movies" started at 23:00:01 UTC and reached its new Archive folder (4,124 files) at 23:02:10. In the scanner rows I exported, Archive is missing from the 13:16–13:17 scan and appears with 0 files at 13:23:18. Between 23:03 and 23:20 the scan logged metadata: rebound skeleton to existing item 5 times. Those are all of that message's rows before the reproduction:

New folder in library 1 Archive Now a version of The receiving movie's other file
Batman (1943) [imdb-tt0035665][tmdb-125249] Bataan (1943), tmdb 43506, imdb tt0035664 library 6 "Movies-NotRated", added 2026-08-30
Broadway (1929) [imdb-tt0019725][tmdb-130717] The Broadway Melody (1929), tmdb 65203, imdb tt0019729 library 6, added 2026-08-30
His and Hers (1961) [imdb-tt0054973][tmdb-287128] Rocco and His Brothers (1960), tmdb 8422, imdb tt0054248 library 6, added 2026-08-30
The Traitors (1962) [imdb-tt0057599][tmdb-299287] The Counterfeit Traitor (1962), tmdb 43013, imdb tt0055871 library 6, added 2026-08-30
Monk (1968) [imdb-tt1864420][tmdb-595980] Monk in Europe (1968), tmdb 595983, imdb tt1864421 library 1 Archive, added in the same scan 0.43 s after the Monk file; the merge came 1.7 s later
  • For all five new folders, movie-tmdb-<tag> returns 404.
  • Library roots lists the Batman and Monk folders as resolved with their tagged IDs and "override_source": "none", and the same for Bataan's own folder in library 6.
  • Each receiving movie's TVDB ID resolves on thetvdb.com to that movie itself (Bataan's 66484 → /movies/bataan, and so on).
  • TMDB lookups through the server (POST /api/v2/admin/items/{id}/match/search with tmdb_id) return, for each of the 10 movies, its own IMDb ID and no TVDB ID.
  • Titles and years of the pairs: Batman / Bataan (1943 / 1943), Broadway / The Broadway Melody (1929 / 1929), His and Hers / Rocco and His Brothers (1961 / 1960), The Traitors / The Counterfeit Traitor (1962 / 1962), Monk / Monk in Europe (1968 / 1968).

What still works: Monk in Europe, also new in that scan, got its own item. Library roots reads the tags correctly. I didn't check how the other Archive files matched, beyond these five log rows.

Older merges in library "Movies-4K" may be related. That's how I noticed the problem: I couldn't find Spider-Man: No Way Home in the web app or the Android app, because its files were inside "3 Way". Those cases look different and have no logs, so I'll add them in a comment.

Steps to reproduce

This was done on my server. I haven't tried it on a clean server; an untested idea for that is under Technical notes.

Starting point (2026-10-11, build 1258 · 3f171de):

  • Library 1 "Movies" (folders [MOVIES-ROOT-1]/1980 … /2020 and [MOVIES-ROOT-1]/Archive) and library 6 "Movies-NotRated" (one sibling folder under [MOVIES-ROOT-1]) are both of type movies, with metadata providers TMDB, MDBList and NFO in that order.
  • "Bataan (1943)" (movie-tmdb-43506: tmdb 43506, imdb tt0035664, tvdb 66484) has two versions:
    • file 80798 in library 6, folder Bataan (1943) [imdb-tt0035664][tmdb-43506];
    • file 1298283 in library 1, [MOVIES-ROOT-1]/Archive/Batman (1943) [imdb-tt0035665][tmdb-125249]/Batman (1943) [imdb-tt0035665][tmdb-125249][DVD][AC3 2.0][x264].mkv. The 2026-10-10 merge attached it.
  • I haven't checked whether the Batman, Bataan, Monk or Monk in Europe folders contain .nfo files.
  1. With an admin session, detach the Batman file without saving an identity override:
    POST /api/v2/admin/items/movie-tmdb-43506/split
    {"file_ids": ["1298283"], "target": {"unmatched": true}, "history_mode": "keep", "persist_override": false, "dry_run": false}
    
    The response is 200 with "target_content_id": "local-[LOCAL-ID-1]", "files_moved": 1, "root_overrides": [] and "file_overrides": []. I used the API because of the web app's Split Versions → Detach as unmatched (identify later): by my reading of the code, it sends no persist_override, so the server would save an override carrying the source item's title (admin_split.go:260, :440-441). I didn't try it in the web app.
  2. Don't start a scan; the split rescans the folder by itself. Wait about 30 s. Here the rescan row came at 12:29:37.004 and the "movie file queue sync" row at 12:29:37.360.
  3. Look for the log row metadata: rebound skeleton to existing item with from_content_id local-[LOCAL-ID-1] and to_content_id movie-tmdb-43506 (here at 12:30:04.750).
  4. Check the result:
    • GET /api/v2/admin/items/movie-tmdb-43506/files lists files 80798 and 1298283 again (polled right after the rebind row, and again at 12:44:55).
    • GET /api/v2/admin/items/movie-tmdb-125249/files returns 404 (polled), and so does GET /api/v2/catalog/items/movie-tmdb-125249 (at 12:44:55).

Expected behavior

The Batman file should become its own movie, movie-tmdb-125249, just as Monk in Europe became its own movie in the same scan. A folder tagged with a TMDB and an IMDb ID should not be merged into a movie whose TMDB and IMDb IDs both differ from the tags.

Where the expectation comes from:

Silo version / commit

1258 · 3f171de (built_at 2026-10-10T02:10:41.000Z)

  • On 2026-10-09 the server reported 1201 · ca186fe.
  • The retained logs, which begin after 2026-10-09 12:00 UTC, show one restart, at 2026-10-10 12:43 UTC. That was most likely the upgrade (an inference).
  • Plugins: silo.tmdb 1.2.26 (auto-updated from 1.2.25 at that restart), silo.mdblist 0.4.0, silo.tvdb 1.4.1 (installed, but not in the provider chains of movie libraries 1, 2, 3 and 6), silo.theintrodb 0.1.3, and the Trakt 0.2.0, MDBList 0.2.0 and Floppy 0.3.1 watch-sync plugins.

Deployment

Docker Compose

Area

Libraries, scanning, and metadata

Clients affected

  • Web UI
  • Android
  • iOS/tvOS/macOS
  • Jellyfin-compat client (Infuse, Findroid, ...)
  • Other/not client-specific

Client app and device

Not client-specific: the server's catalog is wrong. I saw the older No Way Home case in the web app in Firefox, and in Silo for Android 1.0.0 (20) from Google Play on a Google Pixel 6a, Android 17.

Media and playback details

Not a playback problem. The reproduced file is Batman (1943) [imdb-tt0035665][tmdb-125249][DVD][AC3 2.0][x264].mkv. It's the only video file in its folder (Library roots: observed_file_count 1).

Diagnostics report reference

No response

Relevant logs

# Admin logs API (GET /api/v2/admin/logs/app), rows exactly as returned, one per line.
# The API returns newest first; sections marked "oldest first" were reversed or merged.
# Redactions: [NODE-ID-1] = the server's node ID; [MOVIES-ROOT-1] = the parent folder that holds
# library 1's folders and library 6's folder; local-[LOCAL-ID-1] = the local content ID the split
# created (derived from the file's absolute path; the same value in every row).
# All 69 rows in the reproduction window, and all 307 rows in 2026-10-10 23:03:40-23:04:00
# (around the first Batman merge), are level info. None is a warn row.
#
# The reproduction, 2026-10-11 12:29:30-12:30:15 UTC, oldest first (69 rows)
# [... 64 apiv2 and playback rows omitted ...]
{"id": "27245003", "timestamp": "2026-10-11T12:29:35.275Z", "level": "info", "component": "api", "message": "admin split: item split", "node_id": "[NODE-ID-1]", "attrs": {"actor_user_id": 1, "component": "api", "files_moved": 1, "history_ambiguous": 0, "history_mode": "keep", "history_moved": 0, "progress_moved": 0, "source_content_id": "movie-tmdb-43506", "target_content_id": "local-[LOCAL-ID-1]", "target_created": true}}
{"id": "27245006", "timestamp": "2026-10-11T12:29:37.004Z", "level": "info", "component": "scanner", "message": "scanner: discovered files", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "files": 1, "folder_id": 1, "scope": "[MOVIES-ROOT-1]/Archive/Batman (1943) [imdb-tt0035665][tmdb-125249]"}}
{"id": "27245007", "timestamp": "2026-10-11T12:29:37.357Z", "level": "info", "component": "scanner", "message": "metadata: series root queue sync", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "folder_id": 1, "scope": "[MOVIES-ROOT-1]/Archive/Batman (1943) [imdb-tt0035665][tmdb-125249]"}}
{"id": "27245008", "timestamp": "2026-10-11T12:29:37.360Z", "level": "info", "component": "scanner", "message": "metadata: movie file queue sync", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "folder_id": 1, "scope": "[MOVIES-ROOT-1]/Archive/Batman (1943) [imdb-tt0035665][tmdb-125249]"}}
{"id": "27245044", "timestamp": "2026-10-11T12:30:04.750Z", "level": "info", "component": "metadata", "message": "metadata: rebound skeleton to existing item", "node_id": "[NODE-ID-1]", "attrs": {"component": "metadata", "from_content_id": "local-[LOCAL-ID-1]", "item_type": "movie", "to_content_id": "movie-tmdb-43506"}}
#
# Every row matching q=rebound skeleton to existing item from before the reproduction, newest first
{"id": "27124366", "timestamp": "2026-10-10T23:20:54.439Z", "level": "info", "component": "metadata", "message": "metadata: rebound skeleton to existing item", "node_id": "[NODE-ID-1]", "attrs": {"component": "metadata", "from_content_id": "movie-tmdb-299287", "item_type": "movie", "to_content_id": "movie-tmdb-43013"}}
{"id": "27122372", "timestamp": "2026-10-10T23:13:14.281Z", "level": "info", "component": "metadata", "message": "metadata: rebound skeleton to existing item", "node_id": "[NODE-ID-1]", "attrs": {"component": "metadata", "from_content_id": "movie-tmdb-595980", "item_type": "movie", "to_content_id": "movie-tmdb-595983"}}
{"id": "27122134", "timestamp": "2026-10-10T23:10:54.549Z", "level": "info", "component": "metadata", "message": "metadata: rebound skeleton to existing item", "node_id": "[NODE-ID-1]", "attrs": {"component": "metadata", "from_content_id": "movie-tmdb-287128", "item_type": "movie", "to_content_id": "movie-tmdb-8422"}}
{"id": "27120234", "timestamp": "2026-10-10T23:04:55.483Z", "level": "info", "component": "metadata", "message": "metadata: rebound skeleton to existing item", "node_id": "[NODE-ID-1]", "attrs": {"component": "metadata", "from_content_id": "movie-tmdb-130717", "item_type": "movie", "to_content_id": "movie-tmdb-65203"}}
{"id": "27119758", "timestamp": "2026-10-10T23:03:52.271Z", "level": "info", "component": "metadata", "message": "metadata: rebound skeleton to existing item", "node_id": "[NODE-ID-1]", "attrs": {"component": "metadata", "from_content_id": "movie-tmdb-125249", "item_type": "movie", "to_content_id": "movie-tmdb-43506"}}
#
# The 2026-10-10 scan: first component=scan queue row between 22:55 and 23:01
# [... 10 later scan queue rows omitted ...]
{"id": "27118070", "timestamp": "2026-10-10T23:00:01.354Z", "level": "info", "component": "scan queue", "message": "scan queue: progress", "node_id": "[NODE-ID-1]", "attrs": {"library_id": 1, "matched_files": 0, "message": "Preparing scan", "phase": "preparing", "processed_files": 0, "retried_items": 0, "scan_id": "01M4M0PVC1JS3BWWQC3J7FRYPB", "total_files": 0}}
# Library-1 "scanner: discovered files" rows, 2026-10-10 22:00-23:30, oldest first
# [... 32 rows for other libraries omitted ...]
{"id": "27118114", "timestamp": "2026-10-10T23:00:10.544Z", "level": "info", "component": "scanner", "message": "scanner: discovered files", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "files": 6248, "folder_id": 1, "scope": "[MOVIES-ROOT-1]/1980"}}
{"id": "27118171", "timestamp": "2026-10-10T23:00:23.247Z", "level": "info", "component": "scanner", "message": "scanner: discovered files", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "files": 9249, "folder_id": 1, "scope": "[MOVIES-ROOT-1]/1990"}}
{"id": "27118560", "timestamp": "2026-10-10T23:00:46.453Z", "level": "info", "component": "scanner", "message": "scanner: discovered files", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "files": 14071, "folder_id": 1, "scope": "[MOVIES-ROOT-1]/2000"}}
{"id": "27118809", "timestamp": "2026-10-10T23:01:20.658Z", "level": "info", "component": "scanner", "message": "scanner: discovered files", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "files": 22959, "folder_id": 1, "scope": "[MOVIES-ROOT-1]/2010"}}
{"id": "27118941", "timestamp": "2026-10-10T23:01:58.628Z", "level": "info", "component": "scanner", "message": "scanner: discovered files", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "files": 17732, "folder_id": 1, "scope": "[MOVIES-ROOT-1]/2020"}}
{"id": "27118985", "timestamp": "2026-10-10T23:02:10.741Z", "level": "info", "component": "scanner", "message": "scanner: discovered files", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "files": 4124, "folder_id": 1, "scope": "[MOVIES-ROOT-1]/Archive"}}
# The two "scanner: processing progress" rows from 2026-10-10 23:03:40-23:04:00, oldest first
{"id": "27119572", "timestamp": "2026-10-10T23:03:41.249Z", "level": "info", "component": "scanner", "message": "scanner: processing progress", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "errors": 0, "folder_id": 1, "new": 350, "processed": 350, "scope": "[MOVIES-ROOT-1]/Archive", "total": 4124, "unchanged": 0, "updated": 0}}
{"id": "27119743", "timestamp": "2026-10-10T23:03:51.248Z", "level": "info", "component": "scanner", "message": "scanner: processing progress", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "errors": 0, "folder_id": 1, "new": 396, "processed": 396, "scope": "[MOVIES-ROOT-1]/Archive", "total": 4124, "unchanged": 0, "updated": 0}}
#
# When Archive appeared: library-1 "scanner: discovered files" rows from an export of scanner rows
# covering 2026-10-09 13:22 to 2026-10-10 13:24, oldest first. Archive first appears at 13:23:18 with 0 files.
# [... 1,505 rows for other libraries and other scanner messages omitted ...]
{"id": "26793113", "timestamp": "2026-10-09T23:00:01.423Z", "level": "info", "component": "scanner", "message": "scanner: discovered files", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "files": 6248, "folder_id": 1, "scope": "[MOVIES-ROOT-1]/1980"}}
{"id": "26793118", "timestamp": "2026-10-09T23:00:05.632Z", "level": "info", "component": "scanner", "message": "scanner: discovered files", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "files": 9249, "folder_id": 1, "scope": "[MOVIES-ROOT-1]/1990"}}
{"id": "26793130", "timestamp": "2026-10-09T23:00:18.379Z", "level": "info", "component": "scanner", "message": "scanner: discovered files", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "files": 14071, "folder_id": 1, "scope": "[MOVIES-ROOT-1]/2000"}}
{"id": "26793148", "timestamp": "2026-10-09T23:00:28.754Z", "level": "info", "component": "scanner", "message": "scanner: discovered files", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "files": 22959, "folder_id": 1, "scope": "[MOVIES-ROOT-1]/2010"}}
{"id": "26793201", "timestamp": "2026-10-09T23:00:48.444Z", "level": "info", "component": "scanner", "message": "scanner: discovered files", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "files": 17728, "folder_id": 1, "scope": "[MOVIES-ROOT-1]/2020"}}
{"id": "26866991", "timestamp": "2026-10-10T13:16:50.764Z", "level": "info", "component": "scanner", "message": "scanner: discovered files", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "files": 6248, "folder_id": 1, "scope": "[MOVIES-ROOT-1]/1980"}}
{"id": "26867005", "timestamp": "2026-10-10T13:16:56.025Z", "level": "info", "component": "scanner", "message": "scanner: discovered files", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "files": 9249, "folder_id": 1, "scope": "[MOVIES-ROOT-1]/1990"}}
{"id": "26867028", "timestamp": "2026-10-10T13:17:04.642Z", "level": "info", "component": "scanner", "message": "scanner: discovered files", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "files": 14071, "folder_id": 1, "scope": "[MOVIES-ROOT-1]/2000"}}
{"id": "26867062", "timestamp": "2026-10-10T13:17:17.250Z", "level": "info", "component": "scanner", "message": "scanner: discovered files", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "files": 22959, "folder_id": 1, "scope": "[MOVIES-ROOT-1]/2010"}}
{"id": "26867334", "timestamp": "2026-10-10T13:17:49.086Z", "level": "info", "component": "scanner", "message": "scanner: discovered files", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "files": 17731, "folder_id": 1, "scope": "[MOVIES-ROOT-1]/2020"}}
{"id": "26868346", "timestamp": "2026-10-10T13:22:04.848Z", "level": "info", "component": "scanner", "message": "scanner: discovered files", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "files": 6248, "folder_id": 1, "scope": "[MOVIES-ROOT-1]/1980"}}
{"id": "26868359", "timestamp": "2026-10-10T13:22:10.487Z", "level": "info", "component": "scanner", "message": "scanner: discovered files", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "files": 9249, "folder_id": 1, "scope": "[MOVIES-ROOT-1]/1990"}}
{"id": "26868380", "timestamp": "2026-10-10T13:22:18.295Z", "level": "info", "component": "scanner", "message": "scanner: discovered files", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "files": 14071, "folder_id": 1, "scope": "[MOVIES-ROOT-1]/2000"}}
{"id": "26868417", "timestamp": "2026-10-10T13:22:33.361Z", "level": "info", "component": "scanner", "message": "scanner: discovered files", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "files": 22959, "folder_id": 1, "scope": "[MOVIES-ROOT-1]/2010"}}
{"id": "26868544", "timestamp": "2026-10-10T13:23:08.544Z", "level": "info", "component": "scanner", "message": "scanner: discovered files", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "files": 17731, "folder_id": 1, "scope": "[MOVIES-ROOT-1]/2020"}}
{"id": "26868571", "timestamp": "2026-10-10T13:23:18.843Z", "level": "info", "component": "scanner", "message": "scanner: discovered files", "node_id": "[NODE-ID-1]", "attrs": {"component": "scanner", "files": 0, "folder_id": 1, "scope": "[MOVIES-ROOT-1]/Archive"}}
#
# Restarts in the retained logs (q=graceful shutdown and q=server listening), merged oldest first
{"id": "26861772", "timestamp": "2026-10-10T12:43:17.471Z", "level": "info", "component": "app", "message": "beginning graceful shutdown", "node_id": "[NODE-ID-1]"}
{"id": "26861799", "timestamp": "2026-10-10T12:43:34.884Z", "level": "info", "component": "app", "message": "HTTP server listening", "node_id": "[NODE-ID-1]", "attrs": {"addr": ":8080"}}
{"id": "26861800", "timestamp": "2026-10-10T12:43:34.885Z", "level": "info", "component": "app", "message": "Jellyfin compat server listening", "node_id": "[NODE-ID-1]", "attrs": {"addr": ":8096"}}
{"id": "26861801", "timestamp": "2026-10-10T12:43:34.885Z", "level": "info", "component": "app", "message": "ABS compat server listening", "node_id": "[NODE-ID-1]", "attrs": {"addr": ":13378"}}

Technical notes

Analysis by the AI agent. Line numbers are for main at c32feb1. The functions cited have the same bodies in the running build, 3f171de, but sit at different lines there: service.go gained refresh-debt and episode-linking changes in between. For example, the rebind log line is at L7263 in 3f171de.

Where the merge happens. metadata: rebound skeleton to existing item is logged only in rebindItemByProviderIDsLocked (service.go#L7367-L7396, log at L7390). It has two callers, and the log doesn't say which one ran:

  • mergeAndPersist, when the item is provisional or has no durable provider IDs (L2431-L2434);
  • the end of recoverProviderIDConflict (L7445), which runs after a provider-ID conflict at persist time (L2834, L2896).

Both callers ask findExistingByProviderIDs (L6347-L6382) for an owner. That uses FindContentIDByProviderIDs (provider_id_repo.go#L431), which returns the first item holding any one requested (provider, ID) pair, in tmdb, tvdb, imdb order. If that finds nothing, it falls back to GetByExternalID (item_repo.go#L932), which checks each column on its own. Nothing compares the two items' other IDs, so one shared ID is enough, even when the folder's TMDB and IMDb tags contradict the target.

The new-item dedup in mergeAndPersist (L2380-L2389) uses the same lookup, and it logs nothing. The canonicalize branches of recoverProviderIDConflict (L7431, L7437) are guarded differently. They refuse when both items already have files or library memberships (provider_id_integrity.go:430-431, :508-509).

Which ID was shared: unknown.

  • The reproduction may only show a re-merge. In rebindItemToExistingItem, "dedupe provider ids" (L7516) deletes the source's media_item_provider_ids rows only for providers the target already has rows for, and "move provider ids" (L7527) moves the rest onto the target. If Bataan lacked a row for one of Batman's providers, the first merge would have moved that ID to Bataan, and the reproduction would just find it again. I can't see those rows. The query below would show it.
  • TMDB returns no TVDB ID for 125249, and none for the other nine movies.
  • Neither log window has a warn row. So no NFO or folder hint conflicted with a stored ID or overrode an earlier hint (L9141, L9147), and no search result conflicting with the trusted IDs was retained (L1530-L1531).
  • A hint for a key the item doesn't have yet is added silently (L9150). At initial match, NFO <uniqueid> hints are applied before search (L1488-L1500; docs/architecture/local-nfo-metadata.md:43: "NFO hints beat folder-name hints"). A guess, not checked: a TVDB <uniqueid> in a .nfo in the Batman or Monk folder would produce exactly this.
  • The Debug rows on this path ("provider search result", "search candidates assembled", L1523 and L1548) log the provider, title, year and counts, not IDs, so raising the log level wouldn't show the shared ID.
  • A guess: in every pair the titles share words or letters and the years are at most one apart, so whatever supplied the shared ID may have matched by title.

A read-only query that would show which ID ties each pair together, and when it arrived. A moved row keeps its created_at and gets a new updated_at (L7527):

SELECT content_id, provider, provider_id, created_at, updated_at
FROM media_item_provider_ids
WHERE content_id IN ('movie-tmdb-43506','movie-tmdb-595983','movie-tmdb-8422','movie-tmdb-65203','movie-tmdb-43013')
ORDER BY content_id, provider;

Why the July work doesn't cover it. #319, the fix for #318 (0fb5afe), anchored scan group keys on folder tags. #318's acceptance criterion was "Structured provider tags anchor content-group keys (same tag groups, different tags never merge…)". The folders checked (Batman, Monk) do get their own resolved roots with their own IDs, so the merge happens later, in matching. The repair from #459 needs an existing matched owner of the folder's anchored ID (anchored_identity_repair.go#L485-L489). After a merge the tagged movie has no item, so the repair leaves it alone.

Not duplicates. #1954 fixed an item that kept a stale content ID after Identify; here each receiving item's content ID matches its own tmdb_id. #1824 involves a root identity override; the Batman root has "override_source": "none".

Possible direction (a suggestion, not tested). Refuse the rebind and the new-item dedup when the two items disagree on TMDB or IMDb. #2082 added the same rule for people: a name fallback is accepted only when "no provider ID conflicts". The repair could also split out a root whose anchored ID has no owner.

Untested idea for a clean reproduction. The Monk pair has no history before the scan that merged it. Put Monk (1968) [imdb-tt1864420][tmdb-595980] and Monk in Europe (1968) [imdb-tt1864421][tmdb-595983], with whatever sidecar files they have, into one movie library on a fresh instance (provider chain TMDB, MDBList, NFO), then scan. Without knowing where the shared ID came from, this may not reproduce.

AI harness

Claude Code 2.1.294 (in Agent Office)

AI tool(s)

Claude Code with subagents; GitHub CLI, curl, git, and Python scripts against the Silo admin API

AI model(s)

claude-opus-5-5 (all sessions and subagents)

AI involvement

Fully AI-generated, human verified

Independent or adversarial review

Two rounds of fresh Claude Code subagents reviewed the draft against a sanitized evidence file.

  • Round 1 (evidence, reproducibility, privacy, duplicates) found:

    • a wrong library for Bataan;
    • two log excerpts with unmarked omissions;
    • claims wider than the evidence;
    • no on-demand reproduction;
    • a missing .nfo precondition.

    The agent then reproduced the bug on the server with my approval and rewrote the draft.

  • Round 2 (evidence, reproducibility, privacy) found:

    • a reversed timestamp order;
    • an interval taken across two clocks;
    • a local ID derived from a file path;
    • two more unmarked log filters;
    • an overstated code argument about which provider IDs a merge moves;
    • older Movies-4K cases with a different shape.

    All were fixed. The older cases moved to a follow-up comment.

The duplicate search found no matching open or closed issue or PR. Still open: the query above and the folders' .nfo contents.

Confirmations

  • I searched open and recently closed issues and pull requests, and this is not already reported
  • I reproduced this myself on a real deployment
  • Any logs provided are raw apart from marked redactions and are not AI-summarized; if none were available, I said so above

Activity

  1. added
    bugSomething isn't working
    impact: usabilityCore flow broken or severely blocked
    priority: P1Core-path bug; painful workaround — next after P0
    on Oct 11, 2026
  2. silo-triage commented on Oct 11, 2026

    @silo-triage

    Do the four folders in the Batman/Bataan and Monk/Monk in Europe pairs contain .nfo files? If so, please share only their provider-ID fields (<uniqueid> and any legacy ID fields), with private details removed. This would establish a missing precondition for a clean reproduction without repeating the split on your live library.

  3. amokster88 commented on Oct 11, 2026

    @amokster88
    Author

    None of the four folders contains a .nfo file, so there are no <uniqueid> or legacy ID fields to share:

    • Batman (1943) [imdb-tt0035665][tmdb-125249]
    • Bataan (1943) [imdb-tt0035664][tmdb-43506]
    • Monk (1968) [imdb-tt1864420][tmdb-595980]
    • Monk in Europe (1968) [imdb-tt1864421][tmdb-595983]

    The NFO provider is enabled in these libraries' chains, but it had nothing to read for these titles. So the shared ID didn't come from an NFO identity hint, and the guess under "Which ID was shared" in the report doesn't apply.

    I can't run the media_item_provider_ids query from the report. I have admin access to the server, but no shell or database access, and I found no API that returns those rows. The catalog, Jellyfin-compatible and download-manifest responses only carry the item's tmdb_id, imdb_id and tvdb_id columns.

    AI disclosure: Claude Code 2.1.294, claude-opus-5-5, AI-assisted (I checked the folders; the agent wrote this comment and checked the API contract). Review: n/a.

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

    bugSomething isn't workingimpact: usabilityCore flow broken or severely blockedpriority: P1Core-path bug; painful workaround — next after P0

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions