Die Anweisung, die die falschen 26 Sprachen löschte

Ich hatte die Automatisierung meiner eigenen Website angewiesen, den Blog auf vier Sprachen zu verkleinern. Zwei Tage später stellte ich fest, dass sie dabei still und leise auch 26 Sprachen von der Startseite entfernt hatte, und weder mir noch einem einzigen Besucher war das aufgefallen.
TL;DR
- Eine Anweisung, die eigentlich nur den Blog-Bereich betreffen sollte, wirkte sich stattdessen auf die gesamte Website aus.
- 26 von 30 Sprachen verschwanden von der Startseite, der Lebenslaufseite und aus sämtlichen Navigationstexten.
- Nichts stürzte ab, nichts endete in einem 404, deshalb fiel es zwei Tage lang niemandem auf.
- Die Lösung kam aus der Git-Historie, nicht aus der Erinnerung daran, wie die Seite früher aussah.
- Die eigentliche Lehre: Bevor eine automatisierte Änderung läuft, erst die genaue Liste der betroffenen Dateien benennen und lesen, bevor irgendetwas gelöscht wird.
Warum ich überhaupt weniger Sprachen wollte
Meine Website war innerhalb weniger Monate auf dreißig Sprachen angewachsen: Startseite, Lebenslaufseite und ein Blog, den ich fast alle paar Tage aktualisiere. Wie gefährlich das werden kann, hatte ich schon einmal beschrieben: Maschinelle Übersetzung klingt flüssig genug, um seriös zu wirken, und ist trotzdem falsch genug, um einen in einer Sprache zu blamieren, die man selbst nicht prüfen kann. Startseite und Lebenslauf ändern sich kaum, also konnte ich mit diesem Risiko dort leben. Beim Blog sah es anders aus. Neue Beiträge erscheinen häufig, und für die Übersetzungsqualität eines frischen Artikels auf Estnisch am Tag der Veröffentlichung kann ich schlicht nicht die Hand ins Feuer legen.
Also beschloss ich, die Zahl der Sprachen, in die der Blog übersetzt wird, auf die vier zu reduzieren, die ich mir selbst zutraue zu prüfen: Englisch, Russisch, Deutsch, Tschechisch. Alle anderen bleiben so lange draußen, bis ich einen besseren Weg habe, sie zu verifizieren. Dieser Teil des Plans war vernünftig. Was schiefging, war die Art, wie ich ihn in Auftrag gab.
Ein Satz, der zu weit griff
Ich gab eine einzige Anweisung: Der Blog soll auf vier Sprachen bleiben. Kurz und eindeutig, dachte ich zumindest. Was tatsächlich lief, betraf drei verschiedene Dinge gleichzeitig. Es kürzte korrekt die eigenen Content-Ordner des Blogs auf die gewünschten vier. Es schrieb aber auch die zentrale Sprachliste der Website neu, also die Konfigurationsdatei, die festlegt, welche Sprachen überhaupt existieren, und löschte die Startseiten-Inhalte und Navigationstexte für die übrigen 26.
Das Problem: „der Blog" und „die Sprachliste der gesamten Website" leben in derselben Konfigurationsdatei. Nichts darin unterscheidet, welche Sprachen der Blog unterstützt und welche die Website insgesamt unterstützt. Entfernt man eine Sprache aus dieser Liste, verliert sie jeder Bereich, der diese Liste ausliest, Startseite eingeschlossen, in einem einzigen Schritt. Meine Anweisung nannte einen Abschnitt. Die Änderung, die tatsächlich lief, hatte den Geltungsbereich von allem.
Und genau das machte die Sache gefährlich statt nur falsch: Nichts ging laut kaputt. Kein Fehler, kein 404, kein fehlgeschlagener Build. Die Website hörte einfach still auf, für 26 Sprachen Startseite und Lebenslauf zu generieren, und der Sprachumschalter bot sie nicht mehr an. Ein Besucher, der die Seite bisher auf Portugiesisch gelesen hatte, landete stillschweigend auf Englisch. Gelöscht-und-deshalb-weg sieht exakt so aus wie hat-es-nie-gegeben, und keins von beidem wirft einen Fehler.
Zwei Tage vergingen, bevor ich es bemerkte, und auch das nur zufällig, mitten in einem völlig anderen Fix, als ein „Blog"-Link in der Navigation für eine Sprache, die ich noch für aktiv hielt, auf etwas Merkwürdiges verwies. Dieser eine ins Leere führende Link war der einzige sichtbare Faden zurück zum gesamten Problem.
Was der Diff tatsächlich zeigte
Das eigentliche Versagen liegt nicht im Scope-Fehler selbst. Es liegt darin, dass ich nie die Liste der Dateien geprüft habe, die die Änderung tatsächlich anfassen würde, bevor ich sie laufen ließ. Ich habe eine einzeilige Beschreibung dessen gelesen, was sie tun sollte, und angenommen, das beschreibe auch, was sie tat. Das stimmte nicht.
Die Reparatur begann mit einer Frage: Was hat sich verändert, und wo? Ich habe die Live-Website gegen den letzten Commit vor der „Blog kürzen"-Anweisung ge-difft, und die Antwort war sofort eindeutig: die zentrale Sprachkonfiguration, der Startseiten-Content-Ordner und 26 sprachspezifische String-Dateien, keine davon auch nur in der Nähe des Blog-Verzeichnisses. Git hatte jede dieser Dateien exakt so, wie sie vorher waren. Verloren war eigentlich nichts, nur überschrieben durchs Deployment.
Ich habe Startseite, Lebenslauf und Navigationstexte für alle dreißig Sprachen aus dieser Historie wiederhergestellt und den Blog-Ordner genau so gekürzt gelassen, wie ich es wollte: vier Sprachen, mit Absicht. Ein loser Faden blieb übrig. Der „Blog"-Navigationslink zeigte für eine wiederhergestellte Sprache auf eine Blog-Ausgabe in dieser Sprache, die es nicht mehr gibt. Vier Beiträge extra in 26 weitere Sprachen zu duplizieren, nur um diesen einen Link zu füllen, war es nicht wert, also habe ich das Template so eingestellt, dass er stattdessen auf den englischen Blog verweist, und so belassen.

Was ich beim nächsten Mal anders prüfen würde
Bevor ich heute eine automatisierte Änderung an eine live geschaltete, mehrteilige Website heranlasse, stelle ich eine zusätzliche Frage laut: Nenn mir die genauen Dateien, die das anfasst, nicht das Feature, das es reparieren soll. Ist die Antwort vage, ist das das Signal zu stoppen und zu prüfen, nicht es laufen zu lassen und zu schauen, was passiert. Und bevor irgendetwas gelöscht wird, will ich die tatsächliche Dateiliste vor mir haben, nicht eine einzeilige Zusammenfassung dessen, was die Anweisung wohl gemeint haben soll. Ein Scope-Wort in einer Anweisung, „der Blog", „dieses Team", „nur das Frontend", ist nicht automatisch dasselbe wie der tatsächliche Geltungsbereich der dadurch ausgelösten Änderung, und beides deckt sich nur, wenn das auch wirklich jemand geprüft hat: genau die Frage, die ich jetzt an dich zurückgebe. Was ist die kleinste, am sichersten abgegrenzt geglaubte Anweisung, die du zuletzt gegeben hast und die nie gegen das geprüft wurde, was sie tatsächlich anfasste?
Stack: Hugo · Claude Code · Git
Brauchen Sie sowas für Ihr eigenes Unternehmen? So kann ich helfen →
Die KI-Audit-Kickoff-Checkliste sichern
Fünfzehn Fragen zu Ihren eigenen Prozessen, bevor Sie einen Cent für KI ausgeben. Genau die erste Stunde eines echten Audits, als einseitiges PDF. Tragen Sie Ihre E-Mail ein und Sie bekommen es sofort, dazu hin und wieder eine Nachricht, wenn ich etwas schreibe, das Ihre Zeit wert ist. Kein Spam, Abmeldung mit einem Klick.