AI-Slop-Muster.
Benannte Rückstände in KI-generiertem Code: Kommentare, die die nächste Zeile wiederholen, Casts auf any, verschluckte Fehler, tote Imports, TODO-Stubs. aislop erkennt sie deterministisch. 58 Muster, 10 Zielsprachen. Jede Seite zeigt ein beanstandetes Beispiel, ein sauberes Beispiel und die Regel-ID.
Alle Sprachen · 26
Erzählender Kommentar
Ein mehrzeiliger Kommentarblock, der in Prosa durchgeht, was die Funktion tut. Die Signatur sagt es bereits; die Prosa ist Dekoration.
Muster ansehen →Trivialer Kommentar
Ein einzeiliger Kommentar, der genau wiederholt, was die nächste Codezeile tut. Ihn zu entfernen ändert für den Leser nichts.
Muster ansehen →Verschluckte Exception
Ein try/catch, dessen catch-Block leer ist oder nur einen Kommentar enthält – Fehler verschwinden lautlos, ohne Log, ohne Rethrow, ohne Recovery.
Muster ansehen →Unsichere Type Assertion
Ein `as any`-Cast – umgeht den TypeScript-Checker komplett. Jede Garantie des Typsystems ist für diesen Wert ab da weg.
Muster ansehen →Doppelte Type Assertion
Ein `as unknown as X`-Cast – eine doppelte Notluke, wenn der Compiler ein direktes `as X` ablehnt. Schmuggelt Typen ohne Validierung durch.
Muster ansehen →Unbegründete TypeScript-Direktive
Eine `@ts-ignore`-, `@ts-expect-error`- oder `@ts-nocheck`-Direktive ohne begründenden Kommentar. Bringt den Type-Checker in dieser Zeile für immer zum Schweigen.
Muster ansehen →Verwaister TODO-Stub
Ein `// TODO` ohne Verantwortlichen, Ticket oder Plan zur Erledigung. Die Sorte, die Jahre überlebt.
Muster ansehen →Generische Benennung
Variablen und Parameter namens `data`, `result`, `value`, `temp`, `obj`, `info`, `item`. Namen, die sagen „das ist ein Substantiv“, ohne zu sagen, welches.
Muster ansehen →Ungenutzter Import
Ein Import, auf den kein verbleibender Code mehr verweist. Meist ein Überbleibsel eines Refactorings oder einer Löschung, die der Agent nicht zu Ende geführt hat.
Muster ansehen →Vergessenes console.log
`console.log` (oder `print` in anderen Sprachen), das nach dem Debuggen im Produktionscode stehen geblieben ist.
Muster ansehen →Leere Funktion
Eine Funktion ohne Rumpf – meist ein Platzhalter, den der Agent angelegt hat, damit eine Signatur kompiliert, und dann nicht ausgefüllt hat.
Muster ansehen →Unerreichbarer Code
Code nach einem `return`, `throw`, `break` oder `continue`, der niemals ausgeführt werden kann.
Muster ansehen →Konstante Bedingung
Ein `if` oder `while`, dessen Bedingung eine Konstante ist – `if (true)`, `while (false)`, `if (1)` – und einen toten Zweig im Quellcode hinterlässt.
Muster ansehen →Dünner Wrapper
Eine Funktion, die nur existiert, um eine andere Funktion mit denselben Argumenten aufzurufen – keine Transformation, kein Mehrwert, nur eine zusätzliche Schicht.
Muster ansehen →Doppelter Import
Zwei `import ... from`-Anweisungen für dasselbe Modul in einer Datei. Wer liest, muss an zwei Stellen nachsehen, was eine Anweisung sagen sollte.
Muster ansehen →Doppelt exportierter Typ
Dasselbe exportierte `interface` oder derselbe `type`-Alias, mit gleichem Namen und gleichem Inhalt, in zwei TypeScript-Dateien deklariert. Zwei Quellen der Wahrheit für eine Form.
Muster ansehen →Halluzinierter Import
Ein Import eines Packages, das das Projekt nicht deklariert. Oft ein plausibel klingender, vom Modell erfundener Name, der bei der Installation oder zur Laufzeit scheitert.
Muster ansehen →Hartcodierte ID
Eine Provider-, Tenant- oder Projekt-ID, die als String-Literal in den Quellcode kopiert wurde: eine Stripe-Price-ID, eine Org-ID, ein API-Key. Sie zementiert eine einzige Umgebung im Code.
Muster ansehen →Hartcodierte URL
Eine umgebungsspezifische URL im Quellcode: eine API-Basis, ein Staging-Host, ein Webhook-Endpunkt. Der Code funktioniert in einer Umgebung und ruft sie stillschweigend aus allen anderen auf.
Muster ansehen →Versteckter Fallback
Ein harmlos wirkender Standardwert (`0`, `[]`, `{ ok: true }`), der für fehlende Eingaben oder einen fehlgeschlagenen Aufruf einspringt. Aus einem lauten Fehler wird eine leise falsche Antwort.
Muster ansehen →Meta-Kommentar
Ein Kommentar über die Aufgabe oder die Änderung statt über den Code: "wie in den Anforderungen", "vorher wurde hier X aufgerufen", "nicht mehr nötig". Er hält das Gespräch fest, aus dem der Code entstanden ist.
Muster ansehen →Redundantes try/catch
Ein try/catch, dessen catch nur denselben Fehler erneut wirft. Es fügt Verschachtelung hinzu und suggeriert eine Fehlerbehandlung, die es nicht gibt.
Muster ansehen →Redundante Typumwandlung
`String(x)`, `Number(x)` oder `Boolean(x)` auf einem Parameter, der bereits mit diesem primitiven Typ annotiert ist. Die Umwandlung wiederholt, was das Typsystem schon garantiert.
Muster ansehen →Stille Wiederherstellung
Ein catch- oder except-Block, der eine Meldung ohne den abgefangenen Fehler loggt und weitermacht. Der Fehler wird bemerkt, seine Ursache weggeworfen.
Muster ansehen →Tautologischer Test
Eine Test-Assertion, die zwei feste Literale vergleicht, etwa `expect(true).toBe(true)` oder `assert True`. Sie kann nicht fehlschlagen und beweist nichts über den Code.
Muster ansehen →Unbekannte Suppression-Direktive
Ein Kommentar wie `// aislop-ignore-nextline`, dessen Scope keine echte Direktive ist. Er sieht aus wie eine Unterdrückung und unterdrückt nichts.
Muster ansehen →Python · 8
Bare except
Eine `except:`-Klausel ohne Exception-Typ. Sie fängt alles, auch `KeyboardInterrupt` und `SystemExit`, sodass Strg-C und sauberes Herunterfahren zusammen mit den echten Bugs verschluckt werden.
Muster ansehen →Breites except mit pass
`except Exception: pass` (oder `BaseException`): ein Handler, der jeden gewöhnlichen Fehler fängt und nichts damit macht. Der Fehler hinterlässt keine Spur.
Muster ansehen →Verkettetes dict.get
Ein `.get(key, {})`, dessen leeres Dict als Default direkt in ein weiteres `.get(...)` fließt. Fehlende Daten auf jeder Ebene werden still zu einem leeren Wert.
Muster ansehen →isinstance-Leiter
Vier oder mehr `if`-/`elif isinstance(x, ...)`-Zweige, die dieselbe Variable prüfen. Typ-Dispatch von Hand ausgeschrieben, ein Zweig pro Typ.
Muster ansehen →Mutable Default-Argument
Ein Funktionsparameter mit dem Default `[]`, `{}` oder `set()`. Python wertet den Default einmal aus, sodass sich alle Aufrufe ohne dieses Argument dasselbe Objekt teilen und verändern.
Muster ansehen →Print-Debugging
Ein `print()`-Aufruf, der in Bibliotheks- oder Anwendungscode stehen geblieben ist. Meist ein Trace aus einer Debug-Session, der mit ausgeliefert wurde.
Muster ansehen →range(len())-Schleife
`for i in range(len(items)):` ist eine Indexschleife im C-Stil, wo Python direkte Iteration oder `enumerate` bietet.
Muster ansehen →Repetitiver String-Dispatch
Vier oder mehr `if`/`elif x == "..."`-Zweige, die dieselbe Variable mit String-Literalen vergleichen. Eine ausgeschriebene Dispatch-Tabelle.
Muster ansehen →C# · 13
Async-void-Methode
Eine `async void`-Methode. Aufrufer können sie nicht awaiten, und eine darin geworfene Exception entgeht jedem try/catch der Aufrufer und kann den Prozess abstürzen lassen.
Muster ansehen →Zu breites catch
Ein `catch (Exception)`, das alles abfängt und die gefangene Exception nie verwendet. Probleme, mit denen du nicht gerechnet hast, verschwinden zusammen mit dem einen, das du erwartet hast.
Muster ansehen →Console-Überbleibsel in C#
`Console.Write`/`WriteLine` in Bibliothekscode oder `Debug`/`Trace`-Schreibaufrufe in ausgeliefertem Code. Meist vom Debuggen übrig gebliebene Ausgabe.
Muster ansehen →Catch, das nur weiterwirft
`catch (...) { throw; }`: ein Handler, dessen einzige Anweisung die Exception weiterwirft. Er ändert nichts und fügt nur einen try-Block hinzu, den man lesen muss.
Muster ansehen →If/else-if-Kette
Vier oder mehr verkettete `if`/`else if`-Zweige, die denselben Wert per `==` mit einer Konstante vergleichen. Ein ausgeschriebenes `switch`.
Muster ansehen →Index-for-Schleife
`for (int i = 0; i < items.Length; i++)`, wobei `i` nur zum Lesen von `items[i]` dient. Ein `foreach` mit zusätzlicher Mechanik.
Muster ansehen →Leerprüfung mit Count()
`.Count() > 0` oder `.Count() == 0`, um zu fragen, ob eine Sequenz Elemente enthält. Auf einem lazy Enumerable wird dafür jedes Element durchlaufen, nur um eine Ja/Nein-Frage zu beantworten.
Muster ansehen →NotImplementedException-Stub
`throw new NotImplementedException()` in ausgeliefertem Code. Der Member kompiliert; der Aufrufer scheitert zur Laufzeit.
Muster ansehen →Null-Forgiving-Operator
Ein nachgestelltes `!` (`user!.Name`, `GetValue()!`), das dem Compiler sagt, ein Wert sei nicht null. Es bringt die Nullable-Warnung zum Schweigen, ohne etwas zu prüfen.
Muster ansehen →Redundanter XML-Doc-Kommentar
Ein einzeiliges `/// <summary>Gets or sets the name.</summary>`, das den Member-Namen wiederholt. Es dokumentiert nichts, was die Signatur nicht schon sagt.
Muster ansehen →String-Verkettung in einer Schleife
`result += "..."` in einer Schleife. Strings sind unveränderlich, also allokiert jede Iteration einen neuen String und kopiert den alten: quadratischer Aufwand für eine lineare Aufgabe.
Muster ansehen →Unbegründet unterdrückte Warnung
Ein `#pragma warning disable` ohne Kommentar oder ein `[SuppressMessage]` ohne echte `Justification`. Der Befund des Analyzers ist versteckt, und niemand weiß, warum.
Muster ansehen →Sync over Async
Blockierendes Warten auf einen Task mit `.Result`, `.Wait()` oder `.GetAwaiter().GetResult()`. Es bindet einen Thread und kann unter einem Synchronisationskontext zum Deadlock führen.
Muster ansehen →C und C++ · 8
C-Style-Cast
Ein C-Style-Cast wie `(int)x` oder `(double)total` in C++-Code. Er kann eine static-, const- oder reinterpret-Konvertierung durchführen, und nichts in der Syntax verrät, welche.
Muster ansehen →#define-Konstante
`#define MAX_RETRIES 5` in C++: ein Makro als Konstante. Es hat keinen Typ, ignoriert Scopes und ist verschwunden, bevor der Debugger es sieht.
Muster ansehen →std::endl im Stream
`<< std::endl` als Zeilenumbruch. Es flusht den Stream außerdem jedes Mal, was in Schleifen und bei Dateiausgabe teuer ist.
Muster ansehen →iostream-Überbleibsel
`std::cout` oder `std::cerr` in Bibliothekscode. Meist Debug-Ausgabe, die mit ausgeliefert wurde.
Muster ansehen →Manuelles delete
Ein rohes `delete` oder `delete[]` auf einen Pointer. Ownership wird von Hand verwaltet, also führt ein frühes return oder eine Exception zwischen `new` und `delete` zu einem Leak, und ein zweites `delete` ist undefiniertes Verhalten.
Muster ansehen →Not-implemented-Stub
Eine Funktion, die `std::logic_error` oder `std::runtime_error` mit der Meldung "not implemented" wirft oder `false && "not implemented"` asserted. Sie kompiliert und scheitert zur Laufzeit.
Muster ansehen →NULL statt nullptr
Das `NULL`-Makro in C++-Code. Es ist eine verkappte Integer-Konstante und kann deshalb die falsche Überladung auswählen, wo `nullptr` das nicht kann.
Muster ansehen →using namespace std im Header
`using namespace std;` in einer Header-Datei. Jede Datei, die den Header einbindet, erbt den kompletten `std`-Namespace samt der zugehörigen Namenskonflikte.
Muster ansehen →Go · 1
Rust · 2
Unwrap außerhalb von Tests
`.unwrap()` auf einer `Option` oder einem `Result` in produktivem Rust-Code. Aus einem `None` oder `Err` wird ein Panic für den Aufrufer.
Muster ansehen →todo!- oder unimplemented!-Stub
Ein `todo!()`- oder `unimplemented!()`-Makro in Rust-Code. Es passt typmäßig zu jedem Rückgabetyp und löst einen Panic aus, sobald der Pfad ausgeführt wird.
Muster ansehen →Bewerte dein Repository.
Ein Befehl. Score von 0 bis 100. Jedes Muster oben, bei jeder Änderung. Mechanisches automatisch beheben, den Rest mit vollem Kontext übergeben.
npx aislop scan