Zurück zum Blog
Infrastruktur & DevOps · Essay

Drei Listen sind diesen Monat von ihrer Registry abgedriftet. Nichts wurde rot.

Simon Doba·16. August 2026·7 Min. Lesezeit

Das Teuerste, was ich diesen Monat ausgeliefert habe, war keine schlechte Entscheidung. Es war dieselbe kleine, dreimal, in drei verschiedenen Dateien, und keine meiner Prüfungen hatte zu einer davon etwas zu sagen.

Jedes Mal war es eine von Hand gepflegte Liste neben einer Liste, die es schon gab.

Wie es aussah

Drei Fälle, alle innerhalb von zwei Wochen, alle in einer Codebase, die ich gut kenne.

  • Ein Sitemap mit eigener Routenkopie. Der Generator hielt ein hartkodiertes Array von Slugs, mit einem // keep in sync-Kommentar darüber. Es war nicht in sync. Drei gelöschte Seiten blieben im Sitemap und wurden weiter gecrawlt, nachdem es sie nicht mehr gab, und zwei neue tauchten nie darin auf.
  • Eine Übersichtsseite mit eigener Einträgekopie. Zwei Seiten hatten Detailrouten, Social Cards, Sitemap-Einträge und Prerendering, und standen auf keiner Liste, weil die Übersicht ihr eigenes Array pflegte statt die Registry zu lesen, aus der die Detailroute liest. Nichts auf der Seite verlinkte sie. Sie waren live und unerreichbar.
  • Eine generierte Textdatei, die nicht generiert wurde. Ein maschinenlesbarer Index veröffentlichter Posts, gepflegt durch Hineinschreiben. Er listete drei unveröffentlichte Posts mit vollständigen Abstracts.

Jeder dieser Fälle kam an Typechecker, Linter und Testsuite vorbei, weil keines dieser Werkzeuge eine Meinung dazu hat, ob zwei Listen übereinstimmen.

Warum es jede Prüfung überlebt, die du hast

Eine abgedriftete Liste ist keine kaputte. Sie ist ein gültiges Array gültiger Werte, und jeder Konsument verarbeitet sie korrekt. Der Fehler steckt vollständig in dem, was fehlt, und Fehlendes erzeugt keine Meldung.

Schlimmer noch: Das übliche Symptom ist kein Absturz, sondern ein stilles Überspringen. Eine Seite, die nicht im Index steht, wirft nicht; sie ist einfach nicht da. Ein Slug ohne Eintrag in einer Stil-Map bekommt keine Karte. Ein Post, der nicht gelistet werden sollte, wird gelistet und liest sich einwandfrei.

Damit landet es in genau der Kategorie, in der automatische Prüfungen am schwächsten sind: wohlgeformte, unvollständige Ausgabe. Von der Review-Seite habe ich das beschrieben — die Fehler steckten in selbstsicheren Zusammenfassungen, nicht in irgendetwas, das einen Pfad und einen Wert nannte. Hier dieselbe Form. Die Liste ist die Zusammenfassung einer anderen Liste, und in Zusammenfassungen geht etwas verloren, ohne dass irgendwo ein Widerspruch entsteht.

Die Regel, die ich weitergeben würde

Zwei Teile, in dieser Reihenfolge.

Ableiten statt duplizieren. Wenn die Information in der Codebase existiert, lies sie. Ein Sitemap sollte über die Registry laufen. Eine Übersicht sollte über die Registry laufen. Ein Kommentar mit keep in sync ist die Notiz, dass du dich für einen manuellen Prozess entschieden hast, und der wird irgendwann falsch sein.

Alle drei Fälle oben wurden behoben, indem die zweite Liste gelöscht und die erste importiert wurde. Keiner der Fixes dauerte länger als das Finden.

Wo du nicht ableiten kannst, prüfe Vollständigkeit und scheitere laut. Manchmal trägt die zweite Liste Informationen, die die erste nicht hat — einen Stil pro Eintrag, ein übersetztes Label, eine Beschreibung für ein anderes Publikum. Das ist legitim. Nicht legitim ist, die Einträge zu überspringen, die ihr fehlen.

Die eine Stelle in dieser Codebase, die das richtig macht, ist der Generator für die Social Cards. Jede Route braucht einen Kartenstil, und die Stile sind handgeschrieben, weil sie visuelle Entscheidungen sind. Er vergleicht bei jedem Lauf beide Mengen und weigert sich zu starten, wenn sie auseinanderlaufen:

Blog OG style registry is out of sync; missing: expertise-is-the-ceiling, checking-the-reviewer

Das ist ein lästiger Fehler und der richtige. Die Alternative — erzeuge die Karten, die du kennst, überspring den Rest stillschweigend — hätte zwei Posts ohne Social Preview ausgeliefert und es nie erwähnt. Ein Abbruch kostet eine Minute. Ein stilles Überspringen kostet so lange, bis jemand ein Fehlen bemerkt.

Wo ich die Prüfung hinlegen würde

In den Build, nicht ins Review. Ich habe für die Inhalte in diesem Repo einen Strukturchecker geschrieben und in prebuild gehängt, sortiert so, dass die Validierung vor allem Teuren läuft:

"prebuild": "sync-generated-files && check-content && generate-images"

Generieren zuletzt, weil das Rendern der Bilder Minuten dauert und es keinen Grund gibt, sie für Inhalte auszugeben, die gleich durchfallen. Fail-Fast-Reihenfolge kostet nichts und rettet den gesamten Rest der Pipeline.

Was man vorher wissen sollte: In dem Moment, in dem dieser Checker existierte, meldete er achtzehn bestehende Verstöße über fünf ältere Dateien. Nichts war regressiert. Es war immer so gewesen, und das Fehlen einer Prüfung hatte sich monatelang wie ein Bestehen gelesen.

Zwei der achtzehn waren der Checker, der strenger war als die Regel, die er durchsetzen sollte — behoben habe ich das im Checker, nicht im Inhalt. Damit sollte man rechnen: Der erste Lauf einer neuen Prüfung ist ein Gespräch über die Regel, keine Fehlerliste.

Was das nicht löst

Keiner der drei Drifts wurde von Werkzeug gefunden. Zwei fand ein Mensch, dem auffiel, dass etwas Erwartetes nicht da war. Einen fand ich, während ich über etwas ganz anderes schrieb.

Die Prüfungen, die ich ergänzt habe, verhindern die Wiederholung dieser drei. Gefunden hätten sie sie nicht. Eine Prüfung testet die Regel, die du schon kennst; zu entdecken, dass eine Regel nötig war, bleibt ein Mensch, der ein Fehlen bemerkt — dieselbe Lücke wie beim maschinenlesbaren Design System, wo die Constraints immer nur kodieren konnten, woran ich vorher gedacht hatte.

Next

Die naheliegende Erweiterung ist eine allgemeine Prüfung: für jede Registry in der Codebase sicherstellen, dass jedes andere Array derselben Bezeichner davon abgeleitet ist statt neu aufgeschrieben. Ich vermute, das ist je nach Schreibweise der Bezeichner entweder trivial oder unmöglich, und ich habe es nicht versucht.

Bis dahin mache ich die langweilige Variante: Wenn ich eine Registry anlege, greppe ich vor dem Abschließen nach ihren Bezeichnern und sehe nach, wie viele andere Stellen sie bereits kennen.

Falls dir das auch passiert ist: Hat in deiner Pipeline tatsächlich etwas eine abgedriftete Liste erwischt, oder hat jemand eine Lücke bemerkt? Ich habe nur Geschichten der zweiten Sorte und würde gern eine der ersten hören.

Alle drei Fälle stammen aus einer Codebase über zwei Wochen im Juli und August 2026. Die Zahlen — drei Drifts, achtzehn bestehende Verstöße beim ersten Lauf einer neuen Prüfung — kommen aus diesem Repository, nicht aus einer Schätzung.

Artikel teilen

Baust du an etwas Ähnlichem?

Ich schreibe hier über Setups, die ich selbst benutze. Wenn du an etwas Vergleichbarem arbeitest, würde mich interessieren, wie dein Workflow aussieht.

Schreib mir

Cookie-Einstellungen

Wir nutzen Cookies für Analyse und Verbesserung unserer Website. Datenschutzerklärung