Start·Fehlermeldungen

Fehlermeldungen erklärt

104 Fehlermeldungen — jeweils Bedeutung, Ursache und Vorgehen.

Die Lösungen haben Kosten. git reset --hard verwirft nicht committete Arbeit, ein Force-Push kann Commits von Kolleginnen zerstören, und docker system prune löscht unbenannte Volumes. Wo das zutrifft, sagt der Eintrag es.

Git29

Fast jeder git-Fehler ist eine Verweigerung im Sinne von „das aus diesem Zustand zu tun würde etwas verlieren“; fatal: heißt, git hat ohne jede Änderung abgebrochen, und die hint:-Zeilen unter der ersten enthalten meist die eigentliche Lösung.

fatal: refusing to merge unrelated historiesDie beiden Seiten, die Sie zusammenführen wollen, haben keinen gemeinsamen Vorfahren — für git sind es zwei einander fremde Historien. Typisch entsteht das, wenn Sie lokal mit git init begonnen, einige Commits gemacht, dann ein Remote hinzugefügt haben, das schon eigene Commits enthielt, und dann gepullt haben. --allow-unrelated-histories führt sie zwar zusammen, verschweißt aber zwei fremde Historien in einem einzigen Commit, was später kaum zu trennen ist; bei nur wenigen lokalen Commits ist es sauberer, das Remote frisch zu klonen und die Dateien hineinzukopieren.Your branch and 'origin/main' have divergedIhr Branch und origin/main halten jeweils Commits, die der andere nicht hat — die Historie hat sich in zwei Linien geteilt. Das passiert, wenn Sie lokal committen, während jemand anderes pusht, oder wenn Sie bereits gepushte Commits mit amend oder rebase umgeschrieben haben. git pull --rebase setzt Ihre Commits neu auf die fremden auf und hält die Historie einlinig, gibt Ihren Commits aber neue Hashes; hatten Sie sie schon geteilt, steht dieselbe Arbeit danach zweimal in der Historie — dann ist --no-rebase mit einem einzigen Merge-Commit die sicherere Wahl.fatal: Need to specify how to reconcile divergent branches.Seit git 2.34 rät pull nicht mehr, ob bei auseinandergelaufenen Branches gemergt oder rebased werden soll — es verlangt eine Einstellung und meldet keinen Schaden. Es erscheint, wenn die Branches divergiert sind und pull.rebase nie konfiguriert wurde. pull.ff only ist die sicherste Antwort, weil es nur bei möglichem Fast-Forward zieht und sonst ohne jede Änderung abbricht; pull.rebase true schreibt jedes Mal die Hashes Ihrer lokalen Commits neu, false hinterlässt einen Merge-Commit.CONFLICT (content): Merge conflict in src/app.tsxBeide Seiten haben dieselben Zeilen unterschiedlich geändert, und git kann nicht entscheiden, welche gilt; es hat beide Fassungen zwischen <<<<<<<, ======= und >>>>>>> in die Datei geschrieben und angehalten. Das passiert, wenn Sie und jemand anderes denselben Bereich bearbeiten oder wenn ein Rebase Ihren Commit über eine Änderung genau dieser Zeilen hebt. Öffnen Sie die Datei, bringen Sie sie in die richtige Form, löschen Sie die Markierungen, dann git add und commit. git merge --abort stellt genau den Zustand vor dem Merge wieder her — für Committetes gefahrlos, doch Ihre bereits von Hand gelösten Stellen sind damit verloren.Please commit your changes or stash them before you merge.Dateien mit nicht committeten Änderungen werden auch von den eintreffenden Commits berührt, und git hat sich fürs Anhalten statt fürs Überschreiben entschieden. Es erscheint bei pull oder merge mit schmutzigem Arbeitsbaum. git stash push -u legt diese Änderungen beiseite, damit der Merge durchlaufen kann, und -u nimmt auch unversionierte Dateien mit; allerdings kann git stash pop beim Zurückholen kollidieren, und ein Stash ist neben den Branches unsichtbar und leicht zu vergessen — ein Wegwerf-Commit ist die sicherere Gewohnheit.error: Your local changes to the following files would be overwritten by checkout:Sie wollen auf einen anderen Branch wechseln, doch Dateien, die dort anders aussehen, tragen noch nicht committete Änderungen. Es erscheint bei switch oder checkout mit halb fertiger Arbeit. git stash push -u oder ein Wegwerf-Commit bringt Sie hinüber und später zurück. Das in Suchergebnissen häufige git checkout --force bzw. git switch --discard-changes wechselt zwar, löscht diese nicht committeten Änderungen aber endgültig — nichts hält sie fest, auch das Reflog nicht, es gibt keinen Rückweg.You are currently rebasing branch 'feature' on '8a3f21c'.Ein Rebase hat begonnen und ist mittendrin stehen geblieben; HEAD sitzt auf einem temporären Zustand statt auf Ihrem Branch. Diese Zeile sehen Sie nach einem Konflikt während des Rebase oder nach einem edit- bzw. break-Halt in git rebase -i, wenn Sie statt abzuschließen etwas anderes getan haben. Lösen Sie den Konflikt, git add, und machen Sie mit git rebase --continue weiter, oder nehmen Sie --skip, wenn dieser Commit wegfallen soll. git rebase --abort setzt Sie exakt auf den Stand vor dem Rebase zurück — committete Arbeit bleibt vollständig, doch Ihre bisherigen Konfliktlösungen verschwinden mit.You are in 'detached HEAD' state.HEAD zeigt direkt auf einen Commit statt auf einen Branch-Namen, sodass jeder Commit, den Sie hier machen, ohne Namen bleibt. Hierher gelangt man, indem man einen Commit-Hash oder ein Tag auscheckt, in einem Submodul arbeitet oder weil die CI genau einen Commit ausgecheckt hat. Um das Getane zu behalten, legt git switch -c name genau hier einen Branch an und verliert nichts. Gehen Sie stattdessen einfach mit git switch main weg, zeigt nichts mehr auf Ihre Commits: das Reflog findet sie noch eine Weile, dann räumt die Garbage Collection sie ab.Warning: you are leaving 1 commit behind, not connected to any of your branches:Es warnt, dass Sie im Zustand detached HEAD committet haben und jetzt weggehen, ohne dass ein Branch auf diese Commits zeigt. Es passiert, wenn Sie einen Commit-Hash ausgecheckt, gearbeitet, committet und dann zu einem Branch zurückgewechselt haben. Nehmen Sie den Hash aus der Meldung: git branch rescue 8a3f21c heftet sie an einen Namen, und dieser Befehl ändert nichts weiter — er fügt nur einen Namen hinzu. Sind Sie schon weg, listet git reflog sie noch, aber Commits, auf die nichts zeigt, verschwinden mit der Garbage Collection — standardmäßig nach etwa dreißig Tagen.error: failed to push some refs to 'https://github.com/user/repo.git'Der Server hat Ihren Push abgelehnt, und diese Zeile ist nur die Zusammenfassung — der eigentliche Grund steht in der Zeile ! [rejected] direkt darüber. Meist hat das Remote Commits, die Sie nicht haben, doch ein geschützter Branch, ein serverseitiger Hook oder ein Dateigrößenlimit erzeugen dieselbe Zusammenfassung. Lesen Sie zuerst den Grund; im Normalfall erledigt git pull --rebase && git push die Sache. Gefährlich ist, ohne Lesen --force anzuhängen, denn das kann die Commits einer Kollegin vom Server löschen.! [rejected] main -> main (fetch first)Der Remote-Branch enthält Commits, die Ihr Klon noch nie gesehen hat, sodass ein Push jetzt kein Fast-Forward wäre. Das passiert, wenn eine Kollegin zuerst gepusht hat oder Ihr letzter Fetch lange zurückliegt. git pull --rebase origin main holt diese Commits und setzt Ihre darauf neu auf, danach geht der Push durch. Greifen Sie hier nie zu --force: die Commits, die Sie überschreiben würden, gehören anderen und liegen überhaupt nicht in Ihrem Repository — nichts Lokales kann sie zurückholen.! [rejected] main -> main (non-fast-forward)Ihr Branch ist kein Nachfahre des Remote-Branches, ein Push würde also Commits vom Server aus der Historie fallen lassen. Das passiert, wenn Sie bereits gepushte Commits mit rebase, amend oder reset umgeschrieben haben. War das Umschreiben Absicht und gehört der Branch allein Ihnen, nehmen Sie git push --force-with-lease: es verweigert, wenn sich das Remote seit Ihrem letzten Fetch bewegt hat, und kann daher — anders als das bloße --force — keinen dazwischen eingegangenen Push einer Kollegin stillschweigend löschen. War es keine Absicht, lautet die Antwort pull --rebase und nicht force.Updates were rejected because the remote contains work that you do not have locally.Das ist die Erläuterung hinter einem abgelehnten Push: das Remote enthält Arbeit, die Ihr Klon nicht hat, und ein Push jetzt würde sie entfernen. Es erscheint, wenn mehrere Personen einen Branch teilen oder wenn Sie eine Datei im Webinterface bearbeitet und committet, aber nie geholt haben. Erst git pull --rebase origin main, dann push — und es läuft glatt durch. Trotz dieses Hinweises --force anzuhängen bewirkt genau das, was der Hinweis verhindern soll: die Commits der anderen Person verschwinden vom Server, und wenn nach deren Push niemand geholt hat, existieren sie nirgends mehr.error: src refspec main does not match anyDer Name, den Sie pushen wollten, existiert lokal weder als Branch noch als Tag — und was nicht da ist, lässt sich nicht senden. Das passiert in einem frischen Repository ohne Commits, in dem main noch nicht existiert; oder wenn Ihr lokaler Branch master heißt und Sie main getippt haben; oder es ist einfach ein Tippfehler. git push -u origin HEAD schickt genau den Branch, auf dem Sie stehen, unter seinem echten Namen, und räumt den Namensfehler in einem Schritt aus. Gibt es überhaupt keinen Commit, machen Sie zuerst einen — ein leeres Repository hat nichts zu senden.fatal: The current branch feature has no upstream branch.Für diesen Branch ist kein Gegenstück auf dem Remote vermerkt, daher weiß ein bloßes git push oder git pull nicht, wohin. Das passiert, wenn Sie einen Branch mit git switch -c erzeugt und nie gepusht haben. git push --set-upstream origin feature legt den Branch auf dem Server an und vermerkt die Zuordnung einmalig; danach genügt ein einfaches git push. Der Befehl schreibt nur eine Zeile lokale Konfiguration und einen neuen Branch auf dem Server — er löscht nichts und lässt sich gefahrlos wiederholen.error: cannot lock ref 'refs/remotes/origin/main': is at 8a3f21c but expected 1c2d3e4Als git einen neuen Wert in eine Remote-Tracking-Referenz schreiben wollte, fand es dort einen anderen Wert als den gerade gelesenen und verweigerte das Überschreiben. Häufig passiert das, wenn Ihr Editor im Hintergrund holt, während Sie ebenfalls holen, oder wenn jemand force-gepusht hat und Ihre Tracking-Referenzen aus dem Takt sind. Den Fetch einfach zu wiederholen genügt meist. git remote prune origin räumt Tracking-Referenzen ab, deren Branches oben nicht mehr existieren; es löscht nur die Kopien in Ihrem eigenen Repository und rührt keinen Branch auf dem Server an.fatal: not a git repository (or any of the parent directories): .gitEs gibt kein .git in diesem Verzeichnis und in keinem darüber, git hat also kein Repository gefunden. Das passiert, wenn Sie eine Ebene über oder unter dem Repository stehen, wenn ein Klon in einem anderen Ordner gelandet ist oder wenn Sie git init nie ausgeführt haben. Prüfen Sie zuerst mit pwd, wo Sie stehen, und verwenden Sie git init nur, wenn Sie hier wirklich ein Repository beginnen wollen. git init in einem Unterordner eines bestehenden Repositories erzeugt ein zweites, verschachteltes Repository, das das äußere stillschweigend verdeckt — die Dateien dieses Ordners landen ab dann nie in den äußeren Commits.fatal: remote origin already exists.Der Name origin ist in diesem Repository bereits belegt und kann nicht ein zweites Mal angelegt werden. Ein geklontes Repository hat origin von Anfang an, und die Meldung erscheint, wenn Sie darin einer Anleitung für neue Repositories folgen und git remote add origin ausführen. Sehen Sie zuerst mit git remote -v, wohin origin zeigt; wollten Sie eine andere URL, ändert git remote set-url origin nur das Ziel. Diese Einstellung ist eine Zeile in .git/config, jederzeit umkehrbar und ohne Wirkung auf Ihre Commits.error: pathspec 'featue' did not match any file(s) known to gitgit hat keine Datei, keinen Branch und kein Tag mit diesem Namen gefunden — die Zeichenkette in den Anführungszeichen ist genau das, wonach gesucht wurde. Das passiert bei einem Tippfehler, wenn der Branch nur auf dem Server existiert und Sie nicht geholt haben, oder wenn die Datei in einem anderen Verzeichnis liegt als angenommen. Bei einem Branch: git fetch, dann git branch -a und den Namen mit dem Auge vergleichen; bei einer Datei zeigt git status --short die echten Pfade. Pfade in git-Befehlen werden relativ zum Verzeichnis gelesen, in dem Sie stehen, nicht zur Repository-Wurzel — allein das erklärt viele dieser Fälle.git@github.com: Permission denied (publickey).ssh hat den Server erreicht, aber keinen Schlüssel angeboten, den der Server akzeptiert — es geht um Authentifizierung, nicht um Netzwerk. Das passiert, wenn Sie keinen Schlüssel erzeugt haben, wenn Sie einen haben, ihn aber nie in den ssh-agent geladen haben, oder wenn der öffentliche Schlüssel nicht in Ihrem Konto bei diesem Dienst eingetragen ist. ssh-add ~/.ssh/id_ed25519 lädt den Schlüssel für diese Sitzung in den Agenten, und ssh -T git@github.com meldet, welcher Schlüssel versucht wurde und als wer Sie erkannt werden. Beide Befehle lesen nur; es gibt nichts zu verlieren.remote: Support for password authentication was removed on August 13, 2021.GitHub akzeptiert seit 2021 keine Kontopasswörter über https mehr — Ihr Passwort ist nicht falsch, das Verfahren selbst wird nicht mehr angenommen. Es erscheint, wenn Ihre gespeicherte Anmeldeinformation ein altes Passwort ist oder Sie an der Eingabeaufforderung eines eingetippt haben. Wollen Sie bei https bleiben, geben Sie ein Personal Access Token im Passwortfeld ein; andernfalls wechseln Sie mit git remote set-url origin auf die ssh-Adresse. Die Remote-Adresse zu ändern ist eine Konfigurationszeile in Ihrem eigenen Klon — sie berührt keine Commits und ist jederzeit umkehrbar.fatal: Authentication failed for 'https://github.com/user/repo.git/'Die gesendete Anmeldeinformation wurde abgelehnt — sie ist falsch, abgelaufen oder ein Token ohne den für dieses Repository nötigen Geltungsbereich. Die häufige Falle ist ein abgelaufenes Token, das der Credential-Helper noch zwischenspeichert: es wird ohne jede Rückfrage gesendet, sodass jedes Mal dieselbe Zeile erscheint. Die Zeile git credential reject im Fix entfernt nur diesen gespeicherten Eintrag, sodass Sie wieder gefragt werden und ein frisches Token einfügen können. Sie löscht ausschließlich die gespeicherte Anmeldeinformation und berührt keine Repository-Daten.fatal: Unable to create '/repo/.git/index.lock': File exists.git legt .git/index.lock als Sperre an, während es den Index schreibt; existiert die Datei schon, läuft ein anderes git oder eines ist gestorben und hat sie hinterlassen. Zurück bleibt sie durch einen Editor oder eine IDE, die git im Hintergrund ausführt, oder durch einen mit Ctrl+C abgebrochenen bzw. abgeschossenen Befehl. Stellen Sie sicher, dass kein git läuft, und löschen Sie sie mit rm -f .git/index.lock. Löschen, während ein git-Prozess tatsächlich arbeitet, kann den Index beschädigen — also erst prüfen; ist der Index doch verdorben, baut git reset ihn aus HEAD neu auf und lässt ohne --hard Ihre Dateien unangetastet.nothing to commit, working tree cleanDas ist kein Fehler: git sagt Ihnen, dass sich nichts vom letzten Commit unterscheidet, also hat es nichts getan. Sie sehen es, wenn die bearbeitete Datei von .gitignore erfasst wird, wenn Sie an einem anderen Klon oder Worktree gearbeitet haben als dem, in dem Sie stehen, oder wenn Sie längst committet und es vergessen haben. git check-ignore -v <Pfad> gibt genau die .gitignore-Zeile aus, die eine Datei verbirgt, und git log -1 zeigt, ob die Änderung schon eingegangen ist. Beide Befehle lesen nur.error: unable to unlink old 'dist/main.js': Permission deniedEin Checkout wollte eine Datei durch eine neue Version ersetzen, und das Betriebssystem verweigerte das Entfernen der alten. Das passiert, wenn ein anderes Programm die Datei offen hält — unter Windows besonders häufig — oder wenn Sie im Verzeichnis kein Schreibrecht haben. Schließen Sie, was sie hält — Entwicklungsserver, Editor, Virenscanner — und führen Sie denselben Befehl erneut aus; unter Unix korrigieren Sie die Verzeichnisrechte. Das Wiederholen ist gefahrlos, doch beachten Sie: git ist mittendrin stehen geblieben, der Arbeitsbaum bleibt bis zum Erfolg halb aktualisiert.fatal: bad object 8a3f21cDer angegebene Name löst zu nichts auf, was git lesen kann: entweder liegt das Objekt nicht in diesem Repository, oder es liegt dort und ist beschädigt. Das passiert bei einem Hash aus einem anderen Klon oder einem Shallow Clone, bei einem zu kurz abgeschnittenen Hash oder bei einem nach einem Plattenproblem wirklich zerstörten Objekt. git fsck --full meldet fehlende und kaputte Objekte rein lesend, und ein fremder Hash braucht erst ein git fetch, damit das Objekt hier existiert. Meldet fsck tatsächlich Korruption, ist ein neuer Klon schneller und sicherer als eine Reparatur — kopieren Sie nur zuvor Ihre nicht committeten Dateien an einen sicheren Ort.warning: LF will be replaced by CRLF in package.json.Das ist ein Hinweis, kein Fehler: core.autocrlf ist aktiv, git speichert also LF im Commit, schreibt aber CRLF in Ihre Arbeitskopie. Eine Windows-Installation von git mit Standardwerten setzt autocrlf auf true, daher erscheint es dort bei jedem add. git config core.autocrlf input speichert LF und wandelt beim Auschecken nicht mehr um; die bessere Antwort ist eine .gitattributes im Repository mit * text=auto eol=lf, damit sich jeder Klon gleich verhält. Die Umstellung kann alle Dateien einmalig als geändert erscheinen lassen — ein einmaliges erneutes Auschecken, keine verlorene Arbeit.The file will have its original line endings in your working directoryDas ist die zweite Hälfte des CRLF-Hinweises oben: die Datei auf der Platte behält die Zeilenenden, die sie schon hat, und nur die im Commit gespeicherte Kopie wird normalisiert. Es stammt aus derselben autocrlf-Einstellung, für sich genommen ist also nichts kaputt. Zeigen Diffs aber ganze Dateien als geändert, unterscheiden sich die Zeilenenden im Team: verankern Sie die Regel mit einer .gitattributes im Repository und führen Sie einmal git add --renormalize . aus. Dieser Befehl schreibt nur um, wie Zeilenenden gespeichert werden, nicht den Dateiinhalt.husky - pre-commit hook exited with code 1 (error)Ihr Commit ist nie entstanden: ein Hook — Lint, Tests, ein Formatierer — endete mit einem Code ungleich null, und git hat abgebrochen. Der eigentliche Grund steht nicht in dieser Zeile, sondern in der Ausgabe des Hooks darüber, meist eine Lint-Regel oder ein Typfehler. Das zu beheben, was der Hook gemeldet hat, und erneut zu committen ist die einzige echte Antwort. git commit --no-verify überspringt alle Commit-Hooks und erzeugt tatsächlich einen Commit, hat die Prüfung aber nicht bestanden, sondern das Scheitern nur in die CI verschoben — und unformatierter Code geht direkt an die Kollegen.

npm20

Bei npm steht die Ursache in der ersten code-XXXX-Zeile und nicht in den letzten sechs npm-ERR!-Zeilen, und wenn der Fehler aus dem Abhängigkeitsbaum oder einem Native-Build statt aus eigenem Code kommt, löst das Löschen von node_modules mit erneuter Installation etwa die Hälfte.

npm ERR! ERESOLVE unable to resolve dependency treeAb npm 7 werden peerDependencies-Bereiche erzwungen, und diese Meldung sagt, dass npm keine Versionskombination fand, die alle gleichzeitig erfüllt. Häufig ist das, wenn das zu installierende Paket einen Peer-Bereich hat, der Ihre vorhandene react- oder typescript-Version ausschließt — besonders direkt nach einem Major-Upgrade. Lesen Sie die Zeilen Found: und Could not resolve:, um zu sehen, wer was fordert, und ziehen Sie eines der beiden auf eine passende Version: das ist der eigentliche Fix. npm install --legacy-peer-deps installiert unter vollständiger Missachtung der Peer-Bereiche, bringt Sie also weiter, hinterlässt aber einen Baum, dem die Pakete nie zugestimmt haben — die Laufzeitfehler aus unpassenden Versionen bleiben Ihr Problem.npm ERR! Conflicting peer dependency: react@18.3.1Diese Zeile benennt das tatsächlich kollidierende Paar im ERESOLVE-Bericht: dieses Paket fordert jene Version eines Peers, während Ihr Baum eine andere enthält. Meist bedeutet es, dass die Hauptbibliothek einen Major-Sprung gemacht hat und ein Plugin, das sie nutzt, noch nicht nachgezogen ist. Eine Abfrage per Namen mit npm ls react zeigt als Baum, wer welche Version verlangt hat, und man sieht sofort, welches der beiden bewegt werden muss. Das Plugin zu aktualisieren ist der eigentliche Fix; --force schreibt den unpassenden Baum trotzdem und verbirgt das Problem bis zur Laufzeit.npm WARN react-dom@17.0.2 requires a peer of react@17.0.2 but none is installed.npm 6 warnte nur vor Peer-Abhängigkeiten und installierte sie nie für Sie: das Paket ist da, der Begleiter, den es angeblich braucht, nicht. Es erscheint in einem Projekt, das noch auf npm 6 läuft, oder wenn Sie ein altes Lockfile aus jener Zeit verwenden. Installieren Sie den genannten Peer selbst in einer Version innerhalb des angegebenen Bereichs, dann ist es erledigt. Fehlgeschlagen ist noch nichts, denn dies ist nur eine Warnung — sie kehrt später als Cannot find module zurück oder als zwei Kopien derselben Bibliothek mit unerklärlichen Fehlern.npm WARN deprecated request@2.88.2: request has been deprecatedDer Autor des Pakets hat diese Version als nicht mehr empfohlen markiert: sie wurde installiert und funktioniert weiterhin. Meist steht sie nicht in Ihrer eigenen package.json, sondern ist eine transitive Abhängigkeit, die ein von Ihnen genutztes Paket mitbringt. Eine Abfrage per Namen mit npm ls request zeigt, welche Ihrer direkten Abhängigkeiten sie hereinzieht — dort ist zu reparieren, nicht an diesem Paket. Heute gibt es nichts zu tun: deprecated ist keine Sicherheitslücke, darüber informiert npm audit.npm ERR! npm ci can only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are in sync.npm ci installiert streng das, was das Lockfile festhält, und brach vor dem Start ab, weil package.json etwas verlangt, das im Lockfile nicht steht. Das passiert, wenn jemand package.json von Hand bearbeitet oder darin einen Konflikt gelöst hat, ohne install auszuführen, oder package.json ohne das Lockfile committet hat. Führen Sie lokal einmal npm install aus, damit das Lockfile passt, und committen Sie das Lockfile — das ist der ganze Fix. package-lock.json zu löschen, um weiterzukommen, löst stattdessen alle Abhängigkeiten auf neuere Versionen neu auf und verändert stillschweigend, was Ihr Build enthält.npm ERR! The `npm ci` command can only install with an existing package-lock.json or npm-shrinkwrap.jsonnpm ci läuft ohne Lockfile überhaupt nicht, denn es hat nichts, das ihm die zu installierenden Versionen nennt. Das passiert, wenn package-lock.json in .gitignore steht, nie committet wurde, oder wenn das Verzeichnis, in dem Sie stehen, nicht die Projektwurzel ist. npm install --package-lock-only schreibt das Lockfile, ohne etwas zu installieren, und mit dem Commit funktioniert die CI. Setzen Sie package-lock.json nie in .gitignore: die Garantie, dass die CI zweimal dasselbe baut, ruht auf dieser einen Datei.npm ERR! Invalid Version:Das Feld version in package.json ist kein gültiges Semver, daher kann npm das Paket überhaupt nicht einlesen. Das passiert bei einem handgeschriebenen Wert wie 1.0 oder v1.0.0 oder einer leeren Zeichenkette, besonders nach einem schlecht gelösten Konflikt in dieser Datei. npm pkg set version=1.0.0 schreibt eine korrekte dreiteilige Version zurück. Der Befehl bearbeitet nur package.json und rührt weder node_modules noch das Lockfile an, sodass danach jeder Befehl, der die Datei liest, sofort wieder funktioniert.npm ERR! 404 Not Found - GET https://registry.npmjs.org/@acme/ui - Not foundDie Registry kennt kein Paket dieses Namens — ein 404 ist eine Aussage über den Namen, nicht über Ihr Netzwerk oder Ihre Anmeldedaten. Das passiert bei einem Tippfehler, bei einem zurückgezogenen Paket oder bei einem privaten Scope, an dem Sie nicht angemeldet sind. Ein privates Paket sieht für jemanden ohne Zugriff genauso aus wie ein nicht existierendes — deshalb fallen alle drei Fälle in diese eine Zeile. npm view @acme/ui version bestätigt, ob der Name öffentlich existiert; bei einem privaten Scope prüfen Sie, ob .npmrc Registry und Token für diesen Scope enthält. Beide Prüfungen lesen nur.npm ERR! request to https://registry.npmjs.org/express failed, reason: unable to verify the first certificateDie TLS-Verbindung ist gescheitert: die vom Server vorgelegte Zertifikatskette führt zu einer Stelle, der node nicht vertraut. Überwiegend ist es ein Firmennetz, dessen Proxy den Verkehr öffnet und mit eigenem Zertifikat neu signiert; gelegentlich ein Server, der sein Zwischenzertifikat nicht mitgeschickt hat. npm mit npm config set cafile die Firmenwurzel beizubringen ist der richtige Fix. strict-ssl false lässt diese Zeile ebenfalls verschwinden, schaltet aber die Zertifikatsprüfung vollständig ab — damit kann jeder auf dem Weg Ihnen veränderte Pakete unterschieben. Nicht verwenden.npm ERR! code EINTEGRITYDer Hash des heruntergeladenen Tarballs stimmt nicht mit dem im Lockfile vermerkten überein, also entschied npm, dem Empfangenen nicht zu trauen, und brach ab. Es ist ein beschädigter Cache-Eintrag, ein Proxy, der den Download verändert hat, oder seltener ein Lockfile, dessen integrity-Wert von Hand bearbeitet oder falsch gemergt wurde. npm cache clean --force leert den lokalen Cache, sodass die nächste Installation neu lädt; es löscht nur Cache-Kopien und ist gefahrlos wiederholbar. Tritt es bei einem Paket immer wieder auf, ist der vermerkte integrity-Wert selbst falsch und der Eintrag muss mit npm install neu aufgelöst werden.npm ERR! Error: EACCES: permission denied, access '/usr/local/lib/node_modules'npm wollte in ein Systemverzeichnis schreiben, das Ihrem Benutzer nicht gehört — das Paket ist in Ordnung, Sie haben dort nur kein Schreibrecht. Fast immer ist es npm install -g gegen ein node, das die Paketverwaltung des Betriebssystems an einen Ort wie /usr/local gelegt hat. npm config set prefix ~/.npm-global verlegt globale Installationen in Ihr Heimatverzeichnis, und sobald dessen bin im PATH liegt, kehrt der Fehler nicht zurück. sudo npm install -g funktioniert zwar, hinterlässt aber root-eigene Dateien in Cache und node_modules, die später bei normalen Installationen dasselbe EACCES auslösen; ein Versionsmanager wie nvm beseitigt die ganze Fehlerklasse.npm ERR! enoent ENOENT: no such file or directory, open '/home/me/package.json'npm hat im aktuellen Verzeichnis und darüber nach package.json gesucht und keine gefunden — Sie haben einen npm-Befehl an einer Stelle ausgeführt, die kein Projekt ist. Das passiert, wenn Sie in der Wurzel eines Monorepos stehen, während das Projekt in einem Unterordner liegt, wenn Sie neben dem geklonten Ordner stehen, oder wenn Sie einfach das cd vergessen haben. Die Antwort ist, in den Ordner mit package.json zu wechseln, und ein ls zeigt es am schnellsten. Verwenden Sie npm init -y nur, wenn Sie hier wirklich ein neues Projekt beginnen wollen: im falschen Ordner hinterlässt es eine verwaiste package.json, die später Werkzeuge verwirrt.npm ERR! code ELIFECYCLEEin Skript in package.json endete mit einem Code ungleich null — ELIFECYCLE ist npms Hülle darum, nicht die Ursache. Die Ursache ist, was Ihr Build- oder Test-Skript getan hat, und die eigentlichen Fehlerzeilen stehen darüber. Scrollen Sie zum ersten Fehler hoch, oder führen Sie den nach npm ERR! <pkg>@<ver> <script>: gedruckten echten Befehl von Hand aus, um seine Ausgabe ohne npms Hülle zu sehen. Der folgende Exit-Code sagt ebenfalls etwas: 1 ist ein gewöhnliches Scheitern, 137 heißt, der Prozess wurde getötet, meist wegen Speicher.gyp ERR! build errorEine Abhängigkeit enthält C oder C++, das bei der Installation auf Ihrem Rechner kompiliert werden muss, und diese Kompilierung ist fehlgeschlagen — node-gyp braucht einen Compiler und python. Das passiert, wenn keine Build-Toolchain installiert ist, oder wenn das Paket älter als Ihr node ist und die Header nicht mehr passen. Installieren Sie die Toolchain: xcode-select --install für die Kommandozeilenwerkzeuge unter macOS, build-essential und python3 unter Debian oder Ubuntu, die C++-Workload von Visual Studio unter Windows. Liefert eine neuere Version des Pakets ein vorgebautes Binary für Ihr node, ist ein Upgrade des Pakets deutlich schneller als das Reparieren der Build-Umgebung.Error: Cannot find module 'express'node konnte diesen Namen zu keiner Datei auflösen: er liegt nicht in node_modules, oder Sie haben aus einem Verzeichnis ohne node_modules gestartet. Das passiert, wenn Sie nie installiert haben, wenn eine Installation auf halbem Weg scheiterte und einen unvollständigen Baum hinterließ, oder wenn das Paket in devDependencies steht und Sie mit --omit=dev installiert haben. rm -rf node_modules && npm install baut den Baum aus dem Lockfile neu auf; es ist gefahrlos, verliert nichts und kostet nur die Downloadzeit. Beginnt der Name in den Anführungszeichen aber mit ./, fehlt kein Paket — der Pfad in Ihrem eigenen Code ist falsch.Module not found: Error: Can't resolve './components/Button' in '/app/src'Der Bundler hat diese Datei unter diesem Pfad nicht gefunden — das ist Ihr eigener Import, kein Paket. Es passiert, wenn der relative Pfad eine Ebene verrutscht ist, wenn die Endung fehlt oder falsch ist, oder wenn die Groß- und Kleinschreibung des Dateinamens vom Import abweicht. Letzteres ist das gemeinste: die Dateisysteme von macOS und Windows unterscheiden keine Groß- und Kleinschreibung, es läuft also bei Ihnen und bricht nur in der Linux-CI. Geben Sie das Verzeichnis mit ls aus und vergleichen Sie Zeichen für Zeichen mit dem Import, Großschreibung inbegriffen. Ist der Name ein Paket und kein Pfad, installieren Sie es; in keinem Fall wird etwas gelöscht.Error: error:0308010C:digital envelope routines::unsupportednode 17 brachte OpenSSL 3 mit, das einen alten Hash-Algorithmus aus den Standards entfernte, und ein Werkzeug, das ihn weiter verlangt, stürzt genau in diesem Hash-Aufruf ab. Fast immer ist es ein altes webpack 4 — oder ein Werkzeug, das eines mitbringt — auf einem modernen node. export NODE_OPTIONS=--openssl-legacy-provider schaltet die alten Algorithmen für diesen Prozess wieder ein und ist für einen Build harmlos. Doch damit hält man ein totes Werkzeug am Leben: ein Upgrade auf webpack 5 oder auf die aktuelle Version Ihres Frameworks macht die Option ganz überflüssig.FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memoryDer V8-Heap hat seine Obergrenze erreicht und node hat von sich aus aufgegeben — das Betriebssystem hat es nicht getötet, node entschied, nicht weiter wachsen zu können, und hielt an. Ursache ist eine große Typprüfung oder Bündelung, ein Build mit Source Maps in einem großen Projekt, oder lecker Code, der etwa alles in einem Array anhäuft. export NODE_OPTIONS=--max-old-space-size=4096 hebt die Grenze auf 4 GB und reicht oft, doch die Maschine muss diesen Arbeitsspeicher wirklich haben; ist das Limit eines Containers niedriger, tötet stattdessen das Betriebssystem den Prozess, was als Exit-Code 137 erscheint. Muss die Zahl immer weiter wachsen, ist ein Leck die Ursache und nicht die Grenze.npm WARN EBADENGINE Unsupported engineEin Paket deklariert einen engines-Bereich für node oder npm, den Ihre Umgebung nicht erfüllt — npm warnt nur und installiert dennoch. Das passiert bei einem alten node, das als Systempaket installiert wurde, oder wenn das Projekt auf ein neueres node umgestiegen ist als das in Ihrer Shell. Schalten Sie node mit Ihrem Versionsmanager auf eine Version innerhalb des angegebenen Bereichs; maßgeblich ist die .nvmrc des Projekts oder das engines-Feld in package.json. Standardmäßig ist es nur eine Warnung, doch mit engine-strict=true in .npmrc wird aus derselben Bedingung ein Fehler, der die Installation abbricht.zsh: command not found: tscDie Shell hat den PATH durchsucht und keine ausführbare Datei dieses Namens gefunden — die Installation selbst kann durchaus geglückt sein. Das passiert, wenn npms globales bin-Verzeichnis nicht im PATH liegt, wenn Sie lokal statt global installiert haben und das Binary in node_modules/.bin landete, oder wenn die Shell einen alten PATH im Cache hält. npx tsc --version führt die lokale Kopie aus, ohne den PATH anzutasten — diese eine Zeile trennt also „nicht installiert“ von „nicht im PATH“. Bei einer wirklich globalen Installation hängen Sie die Ausgabe von npm prefix -g plus /bin an den PATH und öffnen eine neue Shell.

JavaScript15

Browser- und Node-Fehler nennen meist, was kaputtging, aber nicht, warum der Wert so wurde — Sie haben undefined gelesen, es war keine Funktion, es war kein JSON — die Stelle zum Reparieren liegt also stromaufwärts der werfenden Zeile, und nur diese Zeile mit ?. und Standardwerten stillzulegen lässt dasselbe Problem weiter entfernt und in schwerer erkennbarer Gestalt wiederkehren.

Uncaught TypeError: Cannot read properties of undefined (reading 'name')Der Wert links vom Punkt ist undefined, und Sie haben eine Eigenschaft davon gelesen; der Name in Klammern ist die gewünschte Eigenschaft, kaputt ist also der Wert davor. Ursachen sind eine noch nicht eingetroffene Antwort, ein nie übergebenes Prop, eine Ebene zu tief wie bei data.user.name, oder arr[0].id auf einem leeren Array. Wo der Wert wirklich optional ist, kürzt user?.name ab — sollte er aber vorhanden sein, verwandelt ?. den Fehler nur in ein undefined, das in der nächsten Zeile scheitert; suchen Sie stromaufwärts, warum es undefined ist. Vor Chrome 78 lautete derselbe Fehler Cannot read property 'name' of undefined.TypeError: items.map is not a functionDer Name existiert, ist aber keine Funktion — gäbe es ihn gar nicht, spräche die Meldung von undefined. Typische Ursachen: etwas, das Sie für ein Array hielten, ist tatsächlich ein Objekt oder eine NodeList; eine API liefert {data: [...]} statt des Arrays; oder der Default-Export eines Moduls hat eine andere Form. Geben Sie es aus, bevor Sie rätseln: ein console.log(typeof items, items) klärt die Hälfte dieser Fälle sofort. Eine NodeList oder ein Set braucht nur Array.from(items); war es aber {data: [...]}, ist Einwickeln falsch und items = res.data die Lösung.RangeError: Maximum call stack size exceededDie Aufrufe stapelten sich tiefer als die Engine erlaubt, und meist ist es keine tiefe, sondern endlose Rekursion. Eine Funktion, deren Abbruchbedingung fehlt oder nie greift, zwei Funktionen, die sich gegenseitig aufrufen, JSON.stringify auf einem Objekt, das sich selbst enthält, oder in React ein Render, das den Zustand setzt, von dem es abhängt. Der Stack in der Konsole wiederholt zwei oder drei Rahmen — dieses Paar ist die Schleife, und dorthin gehört der Basisfall. Braucht die Berechnung wirklich Tiefe, ist das Umschreiben in eine Schleife oder einen expliziten Stack der einzige Weg: im Browser lässt sich das Stacklimit nicht erhöhen.SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSONWas Sie JSON.parse übergeben haben, war HTML und kein JSON. Das in der Meldung zitierte <!DOCTYPE ist der Beweis: der Server hat mit einer HTML-Seite geantwortet — einem 404, einem 502 oder einer Login-Weiterleitung — der echte Fehler liegt also vor dem Parsen, in der Anfrage. Typisch sind die falsche URL, ein Dev-Server-Proxy, der index.html statt der API ausgeliefert hat, oder eine abgelaufene Sitzung mit Weiterleitung zur Anmeldeseite. Prüfen Sie res.ok, bevor Sie res.json() aufrufen, und lesen Sie res.text(), um zu sehen, was wirklich ankam; die URL mit curl -s aufzurufen ist der schnellste Blick. Vor Chrome 111 und Node 20 lautete derselbe Fehler Unexpected token < in JSON at position 0.SyntaxError: Unexpected end of JSON inputDer Parser erreichte das Ende des Dokuments, während er noch JSON las — und fast immer war der Body einfach leer. res.json() auf einem 204 No Content oder auf einer Fehlerantwort ohne Body, ein zweimal gelesener Response-Body, dessen zweiter Lesevorgang leer zurückkommt, oder eine mitten im Schreiben abgeschnittene Datei. Nehmen Sie zuerst den Text und prüfen Sie ihn vor dem Parsen — const t = await res.text(); if (!t) return null; — das ergibt eine exakte Diagnose. Mit JSON.parse(text || 'null') darüberzustreichen lässt eine leere Antwort normal erscheinen; klären Sie zuerst, warum der Server einen leeren Body gesendet hat.TypeError: Failed to fetchDie Anfrage endete ohne Antwort, und der Browser verbirgt den Grund absichtlich: eine CORS-Blockade, eine tote Adresse, ein falsches Zertifikat und eine Werbeblocker-Erweiterung ergeben genau dieselben zwei Wörter. Das ist ein geworfener Fehler und kein Status, ein 404 oder 500 kommt also nie hier an — der Server ist nicht einmal zum Antworten gekommen. Häufig steht direkt darüber in der Konsole oder im Network-Tab eine zweite, genauere Zeile; lesen Sie diese zuerst. Ein Aufruf der URL mit curl -i trennt „Server ist tot“ von „Browser hat verweigert“. Firefox formuliert dieselbe Lage als NetworkError when attempting to fetch resource.Access to fetch at 'https://api.example.com/data' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.Die Anfrage erreichte den Server und eine Antwort kam zurück, doch diese Antwort trug keinen Header, der diesen Origin erlaubt — deshalb weigerte sich der Browser, sie an Ihr JavaScript zu geben. Nur Browser setzen diese Regel durch, weshalb dieselbe URL mit curl funktioniert: es sieht aus, als sei der Server in Ordnung und nur der Browser kaputt. Die Behebung liegt immer beim Server: Access-Control-Allow-Origin: http://localhost:3000 in die Antwort aufnehmen. Das Frontend kann nichts tun, und gehört der Server nicht Ihnen, ist ein Proxy über den eigenen Server der einzige Weg. Allow-Origin: * gilt nicht für Anfragen, die Cookies senden; dort braucht es den exakten Origin plus Allow-Credentials.SyntaxError: Cannot use import statement outside a moduleNode oder der Browser hat diese Datei als CommonJS-Skript gelesen, und darin stand das ESM-Schlüsselwort import. Eine .js-Datei ist CommonJS, solange package.json nichts anderes erklärt; im Browser passiert dasselbe, wenn dem <script>-Tag type="module" fehlt. npm pkg set type=module erklärt das ganze Paket als ESM und behebt es, doch ab dann verlieren alle .js im Paket require und __dirname, sodass die übrigen CommonJS-Dateien mitwandern müssen — soll nur eine Datei umziehen, ist die Umbenennung in .mjs der engere und sicherere Schritt.ReferenceError: require is not defined in ES module scope, you can use import insteadDas ist das genaue Gegenstück zum vorigen Fehler — die Datei wird als ESM gelesen und enthält CommonJS' require. Es passiert fast immer direkt nach dem Hinzufügen von "type": "module" in package.json, während alte Skripte noch im Baum liegen. Soll diese eine Datei in der alten Welt bleiben, ist mv script.js script.cjs die engste Änderung; für den Umzug bedeutet require durch import zu ersetzen auch, __dirname und require.main === module zu ersetzen, die es in ESM nicht gibt.Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/app/src/util' imported from /app/src/index.jsFührt Node ESM aus, behandelt es Import-Pfade wie ein Browser als wörtliche Dateinamen: './util' ist also nicht './util.js', sondern eine Datei, die es nicht gibt. CommonJS probierte Endungen für Sie durch, und TypeScript lässt endungslose Imports beim Kompilieren unangetastet — deshalb wirft ein mit tsc gebautes Projekt beim ersten Lauf mit node einen ganzen Stapel davon. Ergänzen Sie relative Imports um die Endung .js; auch in einer TypeScript-Datei schreiben Sie './util.js', denn Node liest das kompilierte Ergebnis. Paketnamen aus node_modules erhalten keine Endung.ReferenceError: window is not definedDer Code lief in Node auf dem Server, nicht in einem Browser. Node kennt kein window, kein document und kein localStorage; wer also window anfasst, während ein Modul in einem Framework geladen wird, das zuerst serverseitig rendert — etwa Next.js oder Nuxt —, bleibt hier stehen. Oft ist es eine einzelne Zeile außerhalb der Komponente oder schon der Import einer reinen Browser-Bibliothek. Ist die Arbeit browserspezifisch, sichern Sie sie mit typeof window !== 'undefined' ab oder verlegen Sie sie besser in useEffect, der nur im Browser läuft. Ist eine ganze Bibliothek browserspezifisch, nimmt Next.js sie mit dynamic(() => import('./C'), { ssr: false }) aus dem Server-Rendering — um den Preis, dass dieser Teil im servergenerierten HTML fehlt.Hydration failed because the initial UI does not match what was rendered on the serverDas vom Server gesendete HTML und das, was der Browser im ersten Render erzeugte, unterscheiden sich — React konnte beides nicht verbinden. new Date() oder Math.random() im Render, ein Lesen von localStorage oder ein Zeichnen nach window-Breite garantieren zwei verschiedene Ergebnisse; ebenso Markup, das der Browser stillschweigend repariert, etwa ein <div> in einem <p>. Die Regel: im ersten Durchgang genau das rendern, was der Server gerendert hat, und erst nach useEffect ändern. Der Preis: dieser Teil erscheint einen Moment später und fehlt im Server-HTML. React 19 formuliert dieselbe Lage als "the server rendered HTML didn't match the client" und zeigt zusätzlich ein Diff der Unterschiede.Objects are not valid as a React child (found: object with keys {name, id})Der Wert, den React darstellen sollte, ist ein Objekt und keine Zeichenkette oder Zahl; die Schlüsselliste in Klammern verrät, welches Objekt. Meist müsste dort {user.name} stehen, wo {user} steht, oder Sie wollten eine ganze Antwort rendern. Steht statt einer Schlüsselliste found: [object Promise], ist die Ursache eine andere: Sie haben das Ergebnis einer async-Funktion ohne await gerendert. Die Lösung ist, das anzuzeigende Feld auszuwählen; JSON.stringify(user) genügt für einen kurzen Blick beim Debuggen, sollte aber nicht auf dem Bildschirm bleiben.Each child in a list should have a unique "key" prop.Als Liste gerenderte Geschwisterelemente haben kein key, deshalb kann React sie beim nächsten Render nicht denselben Einträgen zuordnen. Sie haben die Elemente mit items.map(...) erzeugt und key weggelassen; es ist nur eine Warnung, die Anzeige entsteht trotzdem — doch sie kehrt als stiller Fehler zurück, sobald sich die Liste ändert: Symptom ist ein Eingabewert oder eine Animation, die auf der falschen Zeile bleibt. Geben Sie eine stabile id aus Ihren Daten. Der Array-Index als key ist nur bei einer Liste sicher, deren Reihenfolge sich nie ändert und in der nichts eingefügt oder mittendrin gelöscht wird; sonst erzeugt er fast genau das Problem, gar kein key zu haben. Seit React 19 fehlt das vorangestellte Warning:.Too many re-renders. React limits the number of renders to prevent an infinite loop.Ein Render hat Zustand gesetzt, dieser Zustand löste ein weiteres Render aus, und React hat die Schleife gekappt, um eine endlose zu verhindern. Fast immer wird eine Funktion aufgerufen, wo sie übergeben werden sollte: onClick={setOpen(true)} läuft bei jedem Render, richtig ist onClick={() => setOpen(true)}. Die anderen üblichen Formen sind das direkte Setzen von Zustand im Rumpf des Renders und ein useEffect, dessen Abhängigkeitsliste den Wert enthält, den er aktualisiert. Verlagern Sie Zustandsänderungen in einen Event-Handler oder einen useEffect, und wenn der Wert sich im Render berechnen lässt, fragen Sie, ob er überhaupt Zustand sein muss.

Python18

Ein Python-Traceback teilt die Antwort in zwei Hälften — die letzte Zeile sagt, was schiefging, die Rahmen darüber sagen, wo — wer also nur die letzte Zeile liest, kennt den Namen und verliert den Ort; und bei den „Wert fehlt“-Fehlern wie NoneType und KeyError liegt die Ursache fast immer in einem Rahmen über dem abgestürzten.

ModuleNotFoundError: No module named 'requests'Python hat alle Verzeichnisse in sys.path durchsucht und kein Modul dieses Namens gefunden. Entweder wurde es nie installiert, oder es liegt bei einem anderen Interpreter — pip install außerhalb einer virtuellen Umgebung und dann Ausführen darin ergibt genau das. Als python -m pip install geschrieben landet es im tatsächlich laufenden Interpreter, und die Diskrepanz verschwindet.error: externally-managed-environmentDieses Python gehört dem Betriebssystem oder Homebrew, und pip weigert sich, dort hineinzuschreiben (PEP 668). Sie haben pip install auf den System-Interpreter angewendet; die Meldung fordert eine virtuelle Umgebung. --break-system-packages tut, was der Name sagt, und kann von apt verwaltete Dateien beschädigt zurücklassen — legen Sie stattdessen ein .venv an und installieren Sie darin.ImportError: cannot import name 'User' from partially initialized module 'models' (most likely due to a circular import)Zwei Module importieren sich gegenseitig, also haben Sie einen Namen aus einem nur halb geladenen Modul verlangt. Es entsteht durch die Form A importiert B und B importiert A und tritt gern direkt nach dem Aufteilen einer Datei auf, wenn ein Type-Hint den Import zurückholt. Ersetzen Sie from y import Thing durch import y und schreiben Sie y.Thing in der Funktion: die Auflösung geschieht später, und der Zyklus stört nicht mehr.IndentationError: unexpected indentDie Zeile ist stärker eingerückt als die vorige, und darüber öffnet nichts einen Block, der diese Stufe rechtfertigt. Meist haben Sie Code eingefügt, der eigene führende Leerzeichen mitbrachte, oder eine if-Zeile gelöscht und deren Rumpf eingerückt stehen gelassen. Entfernen Sie den führenden Leerraum in der gemeldeten Zeile; sieht man den Unterschied nicht, macht cat -A für diese Zeile Leerzeichen und Tabs sichtbar.TabError: inconsistent use of tabs and spaces in indentationIn einem Block sind Tabs und Leerzeichen gemischt, sodass Python nicht entscheiden kann, welche Zeile tiefer liegt. Das passiert beim Einfügen aus einem Editor, der Tabs setzt, oder wenn zwei Personen dieselbe Datei mit anderen Einstellungen bearbeiten; am Bildschirm sehen die Zeilen gleich aus, mit dem Auge finden Sie es nicht. python -m tabnanny app.py nennt die betroffenen Zeilennummern, danach stellen Sie die Datei im Editor durchgängig auf vier Leerzeichen um.SyntaxError: invalid syntaxDer Parser konnte aus dem Gefundenen keine Anweisung bilden, und die Ursache liegt meist in der Zeile davor, nicht in der gemeldeten. Eine nicht geschlossene Klammer oder Anführungszeichen, ein fehlender Doppelpunkt oder das print "x" von Python 2 sind die üblichen Gründe — bei offener Klammer läuft der Parser mehrere Zeilen weiter, bevor er aufgibt. python -m py_compile app.py prüft nur die Syntax, ohne etwas auszuführen, und seit 3.10 sind die Meldungen viel genauer, weshalb ein Python-Update selbst schon Diagnose ist.TypeError: 'NoneType' object is not subscriptableDer Wert, den Sie mit [...] indexieren wollten, ist None. Weiter oben hat etwas stillschweigend None geliefert: ein dict.get() auf einen fehlenden Schlüssel, ein re.match ohne Treffer oder eine Funktion ohne return auf dem gelaufenen Pfad. Prüfen Sie nicht an der Absturzstelle, sondern gehen Sie nach oben und klären, warum es None ist — ein if, das None überspringt, verschiebt denselben Fehler nur in die nächste Zeile.AttributeError: 'NoneType' object has no attribute 'get'Das Objekt links vom Punkt ist None, daher gibt es das verlangte Attribut oder die Methode nicht. Es hat dieselbe Wurzel wie nonetype-not-subscriptable und tritt besonders auf, wenn Sie direkt an eine Funktion anknüpfen, die im Fehlerfall None liefert — etwa find() von BeautifulSoup oder re.search(). Geben Sie zuerst aus, wonach diese Funktion gesucht hat, und behandeln Sie den Zweig ausdrücklich, wenn „nichts gefunden“ ein gültiger Fall ist.KeyError: 'name'Der Schlüssel ist nicht im dict, und die Zeichenkette in Anführungszeichen ist genau der gesuchte Schlüssel — fangen Sie dort an, denn meist ist es ein Tippfehler, ein Groß-/Kleinschreibungsunterschied oder eine API-Antwort mit anderer Struktur als angenommen. Ist der Wert wirklich optional, liefert d.get("name") stattdessen None und d.get("name", 0) einen Standardwert; bei einem Pflichtwert tauschen Sie den Fehler jedoch gegen ein None, das in Ihren Code wandert und viel weiter entfernt scheitert.IndexError: list index out of rangeSie haben eine Position verlangt, die die Liste nicht hat. Bei Länge n ist der letzte gültige Index n-1, deshalb enden range(len(x) + 1) und x[len(x)] immer hier, und x[0] auf einer leeren Liste ist derselbe Fehler — häufig, wenn ein Filter oder split darüber nichts übrig ließ. Die Schleife als for item in items: beseitigt diese Fehlerklasse grundsätzlich, und wenn Sie die Position wirklich brauchen, liefert enumerate(items) sie.ValueError: invalid literal for int() with base 10: '3.5'Sie haben int() eine Zeichenkette übergeben, die es nicht als ganze Zahl lesen kann — der Text in Anführungszeichen ist genau diese Zeichenkette. Ein Dezimalpunkt wie in '3.5', eine leere Zeichenkette, eine Eingabe mit Zeilenumbruch am Ende oder ein Tausendertrennzeichen wie in '1,000' sind die üblichen Gründe. Bei einer Dezimalzahl funktioniert int(float(s)) in zwei Schritten, schneidet den Bruchteil aber ab statt zu runden; bei allem, was ein Mensch eintippt, ist try/except ValueError die ehrliche Lösung.UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byteSie haben eine Datei oder Bytefolge als UTF-8 gelesen und dabei ein Byte getroffen, das UTF-8 nicht erlaubt; die Meldung nennt Position und Byte. Meist ist die Datei cp1252 oder eine andere Altkodierung aus Windows, oder überhaupt kein Text — ein Bild, ein Zip oder gzip-Daten, die Sie nicht entpackt haben. Richtig ist, die echte Kodierung zu ermitteln und sie als encoding= zu übergeben; errors="replace" beendet das Lesen zwar, ersetzt diese Bytes aber durch Fragezeichen, sodass die Daten still beschädigt weiterlaufen.ZeroDivisionError: division by zeroEs wurde durch Null geteilt — und in der Praxis ist der Divisor selten eine literale Null, sondern eine Zählung, die Null ergab. Code, der einen Mittelwert bildet, während die Liste leer blieb, oder ein Filter ohne Treffer, ist die klassische Quelle: mit Entwicklungsdaten läuft es immer, und es fällt erst in der Produktion. Prüfen Sie den Nenner vor der Division und entscheiden Sie, was Null dort bedeutet; 0 zurückgeben, None zurückgeben oder die Ausnahme weiterreichen sind drei verschiedene Entscheidungen, und jede ist irgendwo richtig.RecursionError: maximum recursion depth exceededEine Funktion hat sich tiefer selbst aufgerufen als das Standardlimit von 1000 Rahmen. Viel häufiger als eine wirklich tiefe Berechnung bedeutet das, dass die Abbruchbedingung fehlt oder nie erreicht wird; auch indirekte Rekursion zählt, etwa ein __getattr__ oder eine property, die ihr eigenes Attribut erneut liest. Suchen Sie die zwei oder drei Rahmen, die sich im Traceback wiederholen, und reparieren Sie zuerst den Basisfall. sys.setrecursionlimit() hebt die Grenze, lässt Sie aber den echten C-Stack überschreiten — dann stirbt Python komplett, statt eine Ausnahme zu werfen; als Schleife neu zu schreiben ist der sichere Weg.UnboundLocalError: cannot access local variable 'count' where it is not associated with a valueWenn eine Funktion irgendwo in ihrem Rumpf einem Namen etwas zuweist, behandelt Python diesen Namen als lokal — und Sie haben ihn gelesen, bevor die Zuweisung lief. Das tritt auf, wenn Sie den äußeren Wert desselben Namens erwartet haben, oder beim ersten Schreiben einer Lese-Schreib-Operation wie count += 1. Die übliche Antwort ist, ihn in der Funktion mit count = 0 zu initialisieren; müssen Sie wirklich den Modulwert ändern, tut global count das — um den Preis eines Werts, dessen Schreiber schwer nachvollziehbar werden. Bis 3.10 lautete derselbe Fehler 'local variable referenced before assignment'.TypeError: greet() takes 1 positional argument but 2 were givenSie haben ein Argument mehr übergeben, als die Funktion annimmt, und wenn die Zahlen sich um genau eins unterscheiden, ist es fast immer self. Definieren Sie eine Methode in einer Klasse als def greet(name):, so schickt Python beim Aufruf obj.greet("x") das Objekt als erstes Argument mit — damit sind es zwei. Ist es eine Methode, ändern Sie sie zu def greet(self, name):; braucht sie die Instanz überhaupt nicht, versehen Sie sie mit @staticmethod.PermissionError: [Errno 13] Permission deniedDas Betriebssystem hat diese Operation auf diesem Pfad verweigert. Sie haben in fremden Besitz geschrieben, etwa /var/log oder /usr, oder in ein gemountetes Volume im Container, dessen UID nicht zum Container-Benutzer passt, oder — der übersehene Fall — Ihnen fehlt das Schreibrecht am Verzeichnis statt an der Datei, und genau das braucht das Anlegen einer neuen Datei. Prüfen Sie zuerst Eigentümer und Modus mit ls -ld, und bevor Sie zu sudo greifen, verlegen Sie den Pfad besser dorthin, wo Sie schreiben dürfen: eine unter sudo erzeugte Datei wirft beim nächsten Öffnen ohne sudo denselben Fehler.OSError: [Errno 98] Address already in useDas bind schlug fehl, weil ein anderer Prozess den Port schon hält. Entweder ist der vorige Server nicht ganz gestorben, ein Auto-Reloader hat zwei Kopien gestartet, oder ein Docker-Container veröffentlicht denselben Port bereits. lsof -i :8000 nennt die PID, die ihn hält, damit Sie nur diese beenden — lesen Sie den Prozessnamen, bevor Sie irgendetwas mit kill -9 abschießen. Die errno unterscheidet sich je System: Linux zeigt hier 98, macOS 48.

Build und Typen10

Build-Fehler sind ein Werkzeug, das verweigert, bevor irgendetwas läuft — sie zerbrechen im Moment ihres Auftretens nichts, stellen aber zwei Fragen: reparieren Sie Typ oder Pfad passend zur echten Form, oder schieben Sie diese eine Zeile mit einem as any oder einem Unterdrückungskommentar durch? Und genau hier zeigen sich erstmals die Dinge, die nur auf dem eigenen Rechner stimmen: Groß-/Kleinschreibung, Endungen und Umgebungsvariablen.

error TS2307: Cannot find module 'lodash' or its corresponding type declarations.tsc hat weder das Modul selbst noch Typdeklarationen dafür gefunden, und es ist wichtig, dass die Meldung beides nennt — das Paket kann ganz fehlen oder installiert sein und keine Typen mitbringen. Ist es installiert, fehlen die Typen: npm i -D @types/lodash ergänzt das Begleitpaket, wobei viele moderne Pakete eigene Typen mitliefern und gar kein @types haben. Erscheint dies bei einem relativen Import, prüfen Sie Groß-/Kleinschreibung und die paths in tsconfig — ein Pfad in eigene Dateien hat mit @types nichts zu tun.error TS2339: Property 'user' does not exist on type 'Request'.Dieser Typ deklariert diese Eigenschaft nicht. Ursachen: ein Feld, das der Bibliothekstyp nicht hat (user an Express' Request zu hängen ist der Klassiker), ein Tippfehler, oder das Lesen einer Eigenschaft, die nur ein Mitglied einer nicht eingegrenzten Union besitzt. Den Typ an die echte Form anzupassen ist die Antwort; bei einer Union öffnet Eingrenzen mit 'x' in y oder einem Diskriminanzfeld den Zugriff innerhalb des Zweigs. Mit as any zum Schweigen zu bringen knebelt nur den Compiler: an dieser Stelle geht dann auch ein falsch geschriebener Eigenschaftsname durch.error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.Der Typ, den die Funktion annimmt, und der Typ, den Sie übergeben haben, unterscheiden sich; die Meldung nennt sie in Reihenfolge — zuerst Ihr Wert, dann der erwartete. Der weitaus häufigste Fall ist ein Wert aus einem Formularfeld, einem URL-Query-String oder JSON, der als String dort ankommt, wo eine Zahl erwartet wird. Einmal an der Grenze zu konvertieren ist die Antwort, doch Number(value) liefert bei Misserfolg NaN statt zu werfen — dieses NaN muss aufgehalten werden, und Number.isFinite(n) ist die passende Prüfung.error TS18048: 'user' is possibly 'undefined'.Der Wert kann undefined sein, und Sie haben diese Möglichkeit nicht behandelt; hier fängt tsc ein künftiges Cannot read properties of undefined für Sie ab. Es tritt bei optionalen Feldern, beim Ergebnis eines Array-find() und bei möglicherweise nicht gesetzten Umgebungsvariablen auf. Die Lösung ist zu entscheiden, was bei Fehlen geschieht: früh abbrechen mit if (!user) return null oder mit user?.name abkürzen. Als user!.name zum Schweigen gebracht, erklären Sie eine Garantie — und ist die Garantie falsch, kommt es als Laufzeitausnahme zurück, ohne jedes Netz, das eine Prüfung hinterlassen hätte.error TS7006: Parameter 'req' implicitly has an 'any' type.Der Parameter trägt keinen Typ, und tsc hatte nichts, woraus es schließen könnte — also wurde er implizit any, was noImplicitAny als Fehler wertet. Es tritt in aus JavaScript übernommenen Dateien auf und wenn ein Callback in eine eigene Variable gezogen wird; ein inline geschriebenes items.map(x => ...) hat dagegen Kontext, tsc leitet ab, und dies erscheint nie. Den Typ dort hinzuschreiben ist die Lösung. Sie können auch ausdrücklich any schreiben, doch das schaltet die Prüfung für diesen Parameter vollständig ab — wissen Sie nicht, was es ist, ist unknown ehrlicher und erzwingt eine Eingrenzung vor der Nutzung.Parsing error: Unexpected tokenESLint hat beim Lesen der Syntax angehalten, noch bevor eine Regel auf die Datei angewandt wurde. Viel häufiger als wirklich kaputter Code heißt das: der Parser kennt diese Syntax nicht — eine TypeScript-Datei, die der Standardparser liest, nie aktiviertes JSX, oder Dekoratoren und sehr neue Syntax für einen alten Parser. npx eslint --print-config app.ts auf genau diese Datei angewandt zeigt, welcher parser und welche parserOptions wirklich gelten; fangen Sie dort an, statt zu raten. TypeScript braucht @typescript-eslint/parser, und soll die Datei gar nicht geprüft werden, ist ein Eintrag unter ignores die richtige Antwort.You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.Das ist die Zeile, die webpack nach Module parse failed anfügt: es wollte die Datei als JavaScript lesen, und sie war kein JavaScript. Entweder haben Sie etwas importiert, das umgewandelt werden muss — TypeScript, JSX, CSS, ein Bild, eine .vue-Datei — ohne Regel in module.rules, oder ein Paket in node_modules liefert unkompilierten Quellcode, während dieser Ordner in Ihrem exclude steht. Eine Loader-Regel für diese Endung in module.rules ist die Lösung, und der über der Meldung gedruckte Pfad nennt die Datei, an der es hängen blieb. exclude: /node_modules/ zu löschen macht den ganzen Build merklich langsamer; nur dieses eine Paket auszunehmen ist der bessere Tausch.Failed to resolve import "./utils" from "src/main.ts". Does the file exist?Unter diesem Pfad wurde nichts gefunden, und das ausgegebene "Does the file exist?" zeigt auf die drei Dinge, die wirklich zu prüfen sind: Groß-/Kleinschreibung, die Endung und einen Alias in tsconfig oder vite.config. Die Dateisysteme von macOS und Windows ignorieren Groß-/Kleinschreibung, deshalb funktioniert ./Utils auf Ihrem Rechner und bricht erstmals in der CI oder beim Deployment, wo Linux sie beachtet — dieser Fehler ist die häufigste Gestalt von „bei mir läuft es doch“. git ls-files src | grep -i utils zeigt die Schreibweise, die das Repository tatsächlich enthält. Bei einem Alias wie @/utils müssen resolve.alias in vite.config und paths in tsconfig übereinstimmen; korrigiert man nur eines, schweigt der Editor, während der Build weiter scheitert.You're importing a component that needs useState. This React hook only works in a client component.Im App Router ist jede Komponente standardmäßig eine Server-Komponente, und eine Server-Komponente hat eine Datei importiert, die einen Hook verwendet, der nur im Browser Sinn hat — etwa useState. Die Direktive ist eine einzelne Zeile 'use client' ganz oben in der Datei; sie zieht diese Datei und alles, was sie importiert, in das Client-Bundle. Daher ist es die günstige Wahl, das kleinste Stück zu markieren, das Zustand braucht, statt der ganzen Seite. Umgekehrt hält eine Aufteilung, in der eine Client-Komponente Server-Komponenten als Kinder erhält, das Datenladen auf dem Server. Next.js 13 formulierte dieselbe Lage als "It only works in a Client Component but none of its parents are marked with \"use client\"".The engine "node" is incompatible with this module. Expected version ">=20"Das Paket, das Sie installieren, nennt im Feld engines die benötigten Node-Versionen, und Ihre Version liegt außerhalb dieses Bereichs. Das folgende Expected und Got stellen Anforderung und Ihre Version nebeneinander, mehr braucht es nicht — und tritt das nur in der CI auf, unterscheidet sich deren Node-Version von Ihrer. Ein Upgrade mit nvm install 20 && nvm use 20 ist die direkte Antwort, und dieselbe Version in .nvmrc und in der CI-Konfiguration verhindert erneutes Auseinanderlaufen. yarns --ignore-engines schiebt es beiseite, entfernt aber nur die Warnung und schafft keine Kompatibilität: nutzt das Paket neuere Syntax, scheitert es stattdessen zur Laufzeit mit einem Syntaxfehler. npm meldet dieselbe Lage als EBADENGINE-Warnung und blockiert die Installation standardmäßig nicht.

Docker12

Docker-Fehler werden erst lesbar, wenn man sie einer Schicht zuordnet — der Client erreicht den Daemon nicht, die Registry verweigert, ein RUN scheitert im Build, ein Container stirbt sofort beim Start: das sind vier verschiedene Probleme — und in der Build- und Laufzeitschicht ist die Zeile selbst nicht der Grund: der Grund steht in der Ausgabe des Befehls, der darin lief, und auch der Preis jeder Behebung unterscheidet sich je Schicht.

Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?Der docker-Befehl tut selbst nichts — er fragt über diesen Socket einen Daemon, und niemand hat geantwortet. Entweder läuft der Daemon nicht, Docker Desktop ist unter macOS oder Windows noch nicht fertig gestartet, oder Ihr Benutzer ist unter Linux nicht in der Gruppe docker und darf den Socket nicht öffnen; alle drei ergeben diese eine Zeile. Unter Linux starten Sie ihn mit sudo systemctl start docker, bei Desktop zuerst die App. Im Rechtefall helfen sudo usermod -aG docker $USER und eine neue Anmeldung — bedenken Sie aber, dass diese Gruppe praktisch root-Rechte verleiht.Bind for 0.0.0.0:8080 failed: port is already allocatedSie wollten diesen Host-Port mit -p belegen, doch ein anderer Container oder Prozess hält ihn schon. Meist steht ein früher ohne --rm gestarteter Container noch da — gestoppt oder laufend — oder compose hält einen älteren Container fest. docker ps --filter publish=8080 zeigt direkt auf den Container, der ihn veröffentlicht; ist es doch ein normales Host-Programm, findet lsof -i :8080 es. Nur die Hostseite zu ändern, etwa -p 8081:80, bringt Sie weiter, doch bleibt der alte Container liegen, kollidiert es beim nächsten Mal genauso.Conflict. The container name "/api" is already in use by containerDer mit --name übergebene Name gehört schon einem anderen Container. Namen sind auch über gestoppte Container hinweg eindeutig, nicht nur über laufende — meist hält ihn also ein Container, der gestern gestorben ist: in docker ps unsichtbar, nur in docker ps -a sichtbar. docker rm -f api gibt den Namen frei und zerstört dabei auch die beschreibbare Schicht dieses Containers (benannte Volumes bleiben). Für einen Einwegcontainer verhindert docker run --rm die Lage von Anfang an.failed to register layer: Error processing tar file(exit status 1): no space left on deviceAuf der Platte ist kein Platz, um die Image-Schicht auszupacken. Meist ist nicht das Projekt groß, sondern Docker hält weiter monatealte Images, Build-Cache und Volumes entfernter Container. docker system df zeigt, wie viel in Images, Containern, Volumes und Build-Cache steckt und wie viel davon zurückgewinnbar ist — lesen Sie das, bevor Sie etwas löschen. docker system prune entfernt gestoppte Container, verwaiste Images, unbenutzte Netzwerke und den Build-Cache; ohne diesen Cache ist der nächste Build merklich langsamer. Mit --volumes werden zusätzlich Volumes gelöscht, die an keinem Container hängen — genau dort verlieren Leute ihre Datenbanken.pull access denied for myapp, repository does not exist or may require 'docker login'Die Registry hat Ihnen das Repository nicht gezeigt, und entscheidend ist: die Meldung deckt zwei Ursachen zugleich ab — der Name existiert nicht, oder er existiert und Sie dürfen ihn nicht sehen. Entweder sind Sie für ein privates Repository nicht angemeldet, oder im Namen fehlt Benutzer bzw. Organisation (myapp und myorg/myapp sind verschiedene Repositories), oder der Name ist einfach falsch. Bei einem privaten Image melden Sie sich mit docker login an dieser Registry an; soll es öffentlich sein, prüfen Sie die Schreibweise erneut. Registries unterscheiden bewusst nicht zwischen „nicht vorhanden“ und „nicht erlaubt“, weil die Existenz eines Namens selbst eine Information ist.manifest for myapp:v2 not found: manifest unknownDas Repository wurde gefunden, aber das Tag steckt nicht darin. Anders als pull access denied sagt diese Meldung, dass der Name stimmte — zu prüfen bleibt also nur das Tag: ein gelöschtes oder verschobenes Tag, eine Pipeline, die latest hochgeschoben, aber nie v2 erzeugt hat, oder ein Tag ohne Image für Ihre Architektur. docker manifest inspect myapp:v2 bestätigt, ob das Tag überhaupt auflöst und welche Plattformen es enthält. Auf latest umzuschalten, um weiterzukommen, kostet Sie einen nicht reproduzierbaren Build — korrigieren Sie besser das Tag.unauthorized: incorrect username or passwordDie Registry hat die gesendeten Zugangsdaten abgelehnt. Häufiger als ein Tippfehler im Passwort ist ein Passwort, das an eine Registry ging, die Kontopasswörter gar nicht mehr annimmt — Docker Hub akzeptiert bei aktivierter Zwei-Faktor-Anmeldung nur Access Tokens, und die Registries von GitHub und GitLab wollten immer schon ein Token oder einen Deploy Key. docker logout löscht die gespeicherten Daten, danach docker login erneut mit einem Token. Als echo $TOKEN | docker login -u user --password-stdin übergeben, landet das Token nicht in der Shell-Historie.failed to solve: process "/bin/sh -c npm ci" did not complete successfully: exit code: 1Diese RUN-Zeile in Ihrem Dockerfile endete mit einem Status ungleich Null. Diese Zeile nennt nur, welcher Befehl scheiterte und mit welchem Code; der eigentliche Grund steht in der Ausgabe dieses Befehls darüber, die BuildKit nach Abschluss eines Schritts gern einklappt. Ein erneuter Lauf mit docker build --progress=plain gibt die Ausgabe jedes Schritts vollständig aus; verbirgt eine zwischengespeicherte Schicht einen älteren Fehler, fügen Sie --no-cache hinzu — um den Preis, alles ab dem ersten Schritt neu zu bauen. exit code: 1 ist kein Grund, sondern nur die Tatsache des Scheiterns.COPY failed: file not found in build context or excluded by .dockerignoreCOPY kann nur Dateien aus dem Build-Kontext holen, und dort liegt die Datei nicht. Der Kontext ist das letzte Argument von docker build, also haben Sie meist mit ../x auf einen übergeordneten Ordner gezeigt, oder .dockerignore hat die Datei ausgefiltert — klassisch, wenn node_modules oder *.env ignoriert wird und dann etwas daraus kopiert werden soll. Die Meldung nennt beide Ursachen: lesen Sie zuerst cat .dockerignore und schreiben Sie den Pfad relativ zur Kontextwurzel neu. Den Kontext zu erweitern bedeutet, den ganzen Ordner an den Daemon zu senden, was jeden Build verlangsamt.exec /usr/local/bin/entrypoint.sh: exec format errorDer Kernel hat den Header dieser ausführbaren Datei nicht erkannt, und heute ist das fast immer eine Architekturdiskrepanz — ein auf Apple Silicon gebautes arm64-Image läuft auf einem amd64-Host, oder umgekehrt. Ein Shell-Skript ohne erste Zeile #!/bin/sh erzeugt denselben Wortlaut. docker build --platform=linux/amd64 ist die übliche Antwort, beseitigt die Diskrepanz aber nicht, sondern überdeckt sie mit Emulation: alles, was über QEMU läuft, ist mehrfach langsamer als native Ausführung. Für ein Image, das bleiben soll, ist der Bau beider Architekturen mit buildx der Weg ohne Laufzeitkosten.standard_init_linux.go: exec user process caused: no such file or directoryDer Container wollte seinen Entrypoint starten, und der Kernel antwortete „no such file“ — die Falle ist, dass die Datei offensichtlich vorhanden ist. Die Zeilenenden des Skripts sind CRLF, die erste Zeile liest sich also als #!/bin/sh\r, und der Kernel sucht einen Interpreter, der wörtlich sh\r heißt; ein Klon unter Windows oder ein aktives autocrlf in git erzeugt genau das. dos2unix entrypoint.sh wandelt diese eine Datei um (ohne dos2unix: sed -i 's/\r$//' entrypoint.sh), und eine Zeile *.sh text eol=lf in .gitattributes verhindert die Wiederkehr. Ein Interpreter im #!, den das Image nicht hat — bash in einem alpine-Image — ergibt denselben Wortlaut.OCI runtime create failed: exec: "bash": executable file not found in $PATH: unknownDer Container wurde erstellt, aber das Programm, das er ausführen sollte, war darin nicht im $PATH. Alpine-basierte Images bringen sh und kein bash mit, deshalb endet docker run -it myapp bash oder ein CMD ["bash", ...] genau in diesem Fehler — ebenso jedes Werkzeug, das Sie im Image vermuteten und das nur auf dem Host existiert. docker run --rm -it myapp sh gibt Ihnen eine Shell, um zu sehen, was das Image wirklich enthält. Brauchen Sie wirklich bash, fügt RUN apk add --no-cache bash im Dockerfile es hinzu — um den Preis eines größeren Images.

Eine Fehlermeldung lesen

  • Von der ersten Zeile abwärts lesen. Weiter unten geht es um das Innere des Werkzeugs; die Ursache steht meist oben.
  • Gibt es Datei und Zeilennummer, dort anfangen — nicht der oberste Stack-Frame, sondern die oberste Zeile, die eine eigene Datei nennt.
  • Die Meldung wörtlich suchen, vorher aber eigene Pfade und Variablennamen entfernen; genau die verhindern den Treffer.
  • Dieselbe Lage wird je Werkzeugversion anders formuliert. Passen die Treffer nicht, die Versionsnummer mit in die Suche.
  • Vor dem Einfügen einer Lösung prüfen, was sie verwirft. Manches davon lässt sich nicht zurückholen.

Häufige Fragen

Q. Warum werden die Meldungen nicht übersetzt?

Weil man sie sucht. Das Werkzeug gibt Englisch aus, und eine übersetzte Meldung findet nichts. Nur Bedeutung und Abhilfe folgen der Sprache.

Q. Auf meinem Bildschirm steht es etwas anders.

Werkzeuge formulieren das je Version neu. Stimmt das Skelett, nachdem eigene Pfade und Namen entfernt sind, ist es derselbe Fehler. Bei abweichender Version die Versionsnummer mitsuchen.

Q. Darf ich die Lösung einfach ausführen?

Erst prüfen, was sie verwirft. git reset --hard, ein Force-Push und docker system prune entfernen Unwiederbringliches — die Einträge sagen es, wo es zutrifft.

Q. Wie finde ich einen Fehler, der hier fehlt?

Eigene Pfade, Namen und Zahlen aus der Meldung streichen und den Rest suchen. Dieser Rest ist der Satz der Werkzeugautoren, und er ist es, der trifft.