Der Scan ist nach acht Millisekunden fertig. Null Dateien. Keine Fehlermeldung, kein Timeout, kein Eintrag im Log, der nach einem Problem aussieht. Die Freigabe ist im selben Moment per smbclient lesbar. Trotzdem meldet Kodi: fertig, nichts gefunden.

Das war der erste von drei Fällen, die innerhalb weniger Wochen alle nach „der Scan ist kaputt“ aussahen. Die Mediathek auf holocron ist dabei nicht klein: 232 Filme, 132 Serien, 1282 Episoden, verteilt auf zwei Quellen in derselben MyVideos131.db — eine von PKC 3.12.6 verwaltete Plex-Bibliothek und ein nativer SMB-Pfad auf srv-tatooine. Kodi 21.3, TV-Scraper 1.7.13, das Dateiarchiv liegt auf srv-scarif.

Drei Fälle, drei völlig verschiedene Ursachen. Und eine Lehre, die erst am Ende sauber dasaß: Eine Größe in der Oberfläche ist nicht dasselbe wie „die Datei liegt auf dem Share“.

Das Problem

Die Beschwerden klangen unterschiedlich, liefen aber auf denselben Satz hinaus: „Der Film ist nicht da.“ Mal fehlte ein frisch importierter Titel komplett, mal stand er ganz unten statt bei den neuesten, mal war er vorhanden, wurde aber partout nicht eingelesen. Jedes Mal war die naheliegende Diagnose ein Scan-Fehler. Jedes Mal war es keiner — oder genauer: ein anderer als gedacht.

Die gemeinsame Architektur macht das schwer zu sehen. Die native Bibliothek ist ein zusätzlicher Pfad in derselben Datenbank, die PKC bereits benutzt. Beide Systeme schreiben in dieselben Tabellen, beide haben eigene Vorstellungen davon, welche Felder sie besitzen. Ein Feld, das für PKC eine Selbstverständlichkeit ist, kann für einen nativen Pfad das Gegenteil bedeuten.

Dazu kommt, dass Kodi an drei Stellen gleichzeitig „weiß“, was in der Bibliothek steht: in der Datenbank, im laufenden Prozess und in der XML-Datei der Playlist. Ein neuer Film muss durch alle drei. Bleibt er in einer hängen, sieht das Ergebnis aus wie ein fehlgeschlagener Scan — obwohl der Scan in Wahrheit ganze Arbeit geleistet hat und nur seine Konsumenten etwas anderes glauben.

Story 1: Der Scan, der nichts tat

Ein neuer SMB-Pfad wurde als Kodi-Quelle registriert, die Freigabe war lesbar, der Pfad zeigte auf das richtige Verzeichnis. Der anschließende Bibliotheks-Scan lief durch und meldete Erfolg. Ergebnis: 0 Dateien, Laufzeit 8 bis 12 Millisekunden.

Die Diagnose

Der erste Reflex — Netzwerk, Credentials, SMB — war falsch. Derselbe Pfad ließ sich im selben Moment über Kodis eigenen libsmbclient auflisten. Das Problem lag also hinter der Dateiaufzählung, in der Datenbank.

Der Blick in die path-Tabelle von MyVideos131.db zeigte den Unterschied. Der neue Eintrag war vorhanden, korrekt auf Filme gemappt, mit dem richtigen Scraper. Und er trug noUpdate=1. Genau diesen Wert trugen auch die PKC-Zeilen daneben. Beim Anlegen des Pfades war offensichtlich von der funktionierenden Nachbarzeile kopiert worden — ein Reflex, der bei Datenbankzeilen genauso teuer ist wie bei Konfigurationsdateien.

SELECT idPath, strPath, noUpdate, exclude, scanRecursive
FROM path WHERE strPath LIKE '%Filme%';

Die Abfrage ist unspektakulär, aber sie beantwortet die entscheidende Frage vor jedem Scan: Darf Kodi diesen Pfad überhaupt anfassen? Solange das nicht geklärt ist, ist jede weitere Diagnose am Netzwerk Zeitverschwendung.

Die Ursache

noUpdate=1 heißt nicht „nicht aktualisieren, aber trotzdem lesen“. Es heißt: Dieser Pfad ist vom Library-Update ausgeschlossen. Kodi überspringt ihn vollständig. Der Scan läuft, findet planmäßig nichts, weil er nichts suchen darf, und beendet sich sauber. Die Millisekunden sind kein Timing-Artefakt, sondern die ehrliche Laufzeit für null Arbeit.

Für PKC ist das Flag korrekt: Die Addon-eigene Bibliothek wird von PKC gepflegt, nicht von Kodis Scraper. Ein nativer Pfad braucht das Gegenteil.

Der Fix

Drei Felder in der Pfadzeile: noUpdate=0, exclude=0, scanRecursive=-1. Danach derselbe Scan — und die Bibliothek füllte sich mit 18 Filmen, jeweils mit Poster und Plot, sauber gescrapt und mit eigenem Tag versehen.

Der Client in diesem Setup ist ein ausgemusterter Mini-PC, der ohnehin nur zum Abspielen läuft. Für eine Bibliothek dieser Größe ist ein Refurb-Gerät der 1-Liter-Klasse die naheliegende Wahl — Lenovo ThinkCentre M720q Tiny (i5-8400T, 16 GB, generalüberholt) deckt genau dieses Profil ab. Die eigentliche Lehre kostet allerdings nichts: Bevor man einen Bibliotheks-Scan debuggt, prüft man, ob der Pfad überhaupt zum Update zugelassen ist.

Story 2: Der Film ist neu, die Sortierung weiß das nicht

Wenige Tage später: zwei frisch importierte Filme, beide in der Bibliothek, beide getaggt, beide abspielbar. Und beide standen ganz unten in einer Liste, die nach „zuletzt hinzugefügt“ sortiert war. Der eine stammte aus dem Jahr 2015, der andere aus 2023 — neu geladen, alt einsortiert.

Die Diagnose

Der Verdacht „Scan hat die Metadaten nicht geschrieben“ ließ sich schnell verwerfen. Die Filme hatten ihre IDs, ihre Tags, ihre Poster. Der Fehler lag in einem einzigen Feld: dateadded.

Verglichen wurde dabei nicht die Anzeige, sondern Rohdaten: der Wert aus der Filmtabelle gegen die mtime der Datei auf dem Share. Bei 4 von 4 Stichproben stimmten beide sekundengenau überein. Ein Film trug die mtime 2016-01-20 13:37:44 — und exakt denselben Wert als dateadded. Kein Zufall, kein Zeitzonen-Versatz, sondern eine Ableitung: Kodi setzt dateadded bei nativen SMB-Filmen auf die Datei-mtime.

Von 30 nativen Filmen waren 26 betroffen. Eine Sortierung nach dateadded war damit keine Sortierung nach Import, sondern nach dem Alter des Release-Materials.

Die Ursache

Die Dateien kommen aus einem Release-Workflow. SABnzbd und Unrar erhalten beim Entpacken die gespeicherte Dateizeit des Releases — und die ist so alt wie der Film. Radarr ändert daran nichts: fileDate=none ist genau das, was der Name sagt. Ergebnis: Ein gestern importierter Film trägt die Zeit von 2016, und jede Sortierung nach dateadded schiebt ihn nach unten. Der Scan war korrekt, die Datenbasis war es nicht.

Dazu kam ein zweiter, unabhängiger Grund für dieselbe Wahrnehmung: Die beiden Smart-Playlists für Filme und Serien hatten überhaupt kein <order>-Element. Ohne explizite Sortierung entscheidet die Voreinstellung, und die war nicht „neueste zuerst“. Selbst ein korrektes dateadded hätte die Reihenfolge also nicht gerettet.

Der Fix

Ein Korrekturschritt im Sync-Skript: pro nativem Film dateadded per VideoLibrary.SetMovieDetails auf die Ordner-mtime setzen — die entspricht der Importzeit, nicht der Release-Zeit. Nur bei Abweichung, idempotent, ausschließlich für SMB-Filme, nicht für PKC-Einträge. Der Live-Lauf korrigierte 26 Filme. Ein Wiederholungs-Dryrun meldete NEED_FIX 0.

Zusätzlich bekamen die Playlists ihre Ordnung:

<order direction="descending">dateadded</order>

Danach standen die zuletzt importierten Titel oben. Offen bleibt derselbe Mechanismus bei Serien-Episoden — dort wurde nichts angefasst. Wer eine Serie nach „zuletzt hinzugefügt“ sortiert, sollte das Muster dort ebenfalls prüfen.

Story 3: „does not exist“ — obwohl die Datei da ist

Der dritte Fall war der unangenehmste, weil er sich selbst widersprach. Der Filmordner lag auf der Freigabe, war per smbclient sichtbar, und Kodi schrieb beim Scan ins Log:

Process directory '…/Filme/<Titel> (2026)/' does not exist - skipping scan

Nicht einmal. Zwölfmal über zwei Stunden. Jeder erneute Scan, jeder Catch-up-Lauf, jedes Refresh — dieselbe Zeile. Erst nach einem Neustart des Kodi-Prozesses wurde der Film eingelesen und getaggt.

Die Diagnose

Die Logzeile ist präzise und irreführend zugleich: Sie beschreibt nicht den Zustand des Shares, sondern den Zustand von Kodis eigenem Verzeichnis-Cache. Ein langlebiger Prozess hatte für den nachträglich angelegten Ordner ein negatives Ergebnis zwischengespeichert und lieferte es bei jedem Scan erneut aus. Wiederholen half nicht, weil das Wiederholen genau den Cache traf.

Der naheliegende Gegenversuch — Files.GetDirectory auf den betroffenen Kindordner — änderte nichts. Der Cache-Eintrag für diesen Ordner blieb. Erst der Refresh der Eltern-Auflistung, also des Share-Roots …/Filme/, brachte den Scraper wieder ins Spiel.

Die Ursache

Ein negativer Verzeichnis-Cache in einem langlebigen Kodi-Prozess. Er ist an den Prozess gebunden, nicht an die Datei, und er überlebt jeden Scan. Deshalb sieht die Oberfläche aus wie „Datei fehlt“, obwohl der Share korrekt ist: Der Prozess beantwortet die Frage „existiert dieser Ordner?“ aus dem Gedächtnis, und sein Gedächtnis ist älter als der Ordner. Ein Neustart hilft, weil er den Cache mitnimmt — nicht, weil er das Netzwerk repariert. Ehrlich dazugesagt: Das ist der belegte Mechanismus, ein kontrollierter Vorher-/Nachher-Repro mit frisch angelegtem Ordner und definiertem Prozesszustand fehlt. Die Beobachtung ist reproduzierbar, der Beweis im Labor steht aus.

Der Fix

Vor jedem Scan wird die Eltern-Auflistung über Kodis JSON-RPC frisch gelesen:

{"jsonrpc": "2.0", "method": "Files.GetDirectory",
 "params": {"directory": "smb://…/Filme/"}, "id": 1}

Das passiert im Catch-up-Skript und in beiden Import-Hooks. Ein Refresh nur auf den Kindordner genügt nachweislich nicht.

Verifiziert wurde das mit frisch angelegten Testordnern im laufenden Prozess: Statt does not exist erschien der Scraper, danach wurden die Testordner wieder entfernt. Der Catch-up meldete in einem Worklog gescannt: 28 OK, 0 Fehler, im anderen 29 OK. Der Widerspruch bleibt stehen — die beiden Läufe sind nicht dieselbe Messung, und ich glätte ihn nicht nachträglich.

Parallel dazu stand noch ein Boot-Problem: Der Startup-Scan lief um 22:36:10, bevor Netz und SMB bereit waren, der Catch-up holte erst um 22:42 nach. Der Boot-Trigger wartet seitdem nicht mehr auf eine feste Zeit, sondern pollt auf Kodi-JSON-RPC und die Lesbarkeit beider Shares; der Timer startet nach OnBootSec=15s, die Bereitschaftsprüfung erledigt den Rest. Offen ist die Gesamtabnahme mit einem echten Import bei ausgeschaltetem Client — belegt sind die einzelnen Teile, nicht der durchgehende Lauf.

Wer den Client dauerhaft laufen lässt statt ihn bei jedem Einschalten neu hochzufahren, umgeht die ganze Klasse von Boot- und Cache-Fenstern. Ein sparsamer Mini-PC wie der Mini-PC N100 Beelink S12 Pro ist dafür die mittlere Preisklasse — kein Muss, aber die ehrlichere Lösung als ein Poll-Intervall zu tunen. Wer zusätzlich transcodiert oder mehrere Räume bedient, ist mit einem Minisforum MS-01 (i5-12600H, Barebone ohne RAM/SSD) in der oberen Klasse besser aufgehoben.

Was du mitnimmst

Ein Scan, der in Millisekunden fertig ist, ist kein schneller Scan. Er ist der Bug. Wer bei Kodi nach „0 Dateien“ sucht, sollte zuerst die Laufzeit lesen: 8 bis 12 Millisekunden bedeuten, dass der Pfad übersprungen wurde, nicht dass die Freigabe leer ist.

Die zweite Lehre ist unangenehmer, weil sie sich durch alle drei Fälle zieht: Jede Größe, die du in der Oberfläche siehst, ist eine eigene Baustelle. Der Playlist-Tag sagt nichts über den Scan. dateadded sagt nichts über den Importzeitpunkt. Und ein does not exist im Log sagt nichts über die Datei auf dem Share. Es sind drei verschiedene Datenschichten — Anzeige, Datenbankfeld, Verzeichnis-Cache — und jede kann einzeln lügen, während die anderen stimmen.

Deshalb ist die Reihenfolge der Diagnose wichtiger als das Werkzeug: erst prüfen, ob der Pfad überhaupt zum Update zugelassen ist (noUpdate), dann das konkrete Feld gegen die Primärquelle vergleichen (mtime gegen dateadded), dann den Prozesszustand statt den Share verdächtigen (Eltern-Listing). Wer diese drei Ebenen auseinanderhält, braucht keinen Neustart auf Verdacht — und keine Nacht, in der der Holocron-Kompressor wieder zwölfmal denselben Ordner für nicht existent erklärt.