Skip to main content
New aislop v0.13.1 patch — calibrates hidden-fallback detection and fixes regex comment-masker false positives. Read the changelog →
← Blog
Pattern Guide · 8 min read

The top 10 AI slop patterns we see often

Which AI slop patterns actually matter? Some teams worry about narrative comments. Others care most about swallowed exceptions. Here is the ranked list we landed on after running aislop against 25 real repos, and the rule that flags each one.

Which AI slop patterns actually matter? Ask ten teams, you get ten answers. Some say narrative JSDoc is the worst. Some say swallowed exceptions. Here is the list we landed on after running aislop against 25 real repos. Ten patterns, ranked by how often they appear and how much risk they add. Each one has a rule ID. Each one is deterministic. A few may already be in your repo.

01

Narrative preamble JSDoc

ai-slop/narrative-comment

The multi paragraph JSDoc that restates, in prose, what the function body already says. It is one of the clearest signals of generated or over-explained code, especially when repeated across a codebase.

/** * Heuristic side-effect detection. Walks an expression subtree * and flags anything that could invoke code when the declaration * initializes. */
export const hasSideEffect = (): boolean => false;

What to do instead. Delete it. If you actually need a directive like @deprecated or @see, keep the tag and nothing else.

02

Trivial "this function does X" comments

ai-slop/trivial-comment

A comment that says the same thing as the name of the line below it. Pure autocomplete residue. Nobody reads it. Nothing reads it.

// Initialize the database connection
initDB()

What to do instead. Delete the comment. If the line is doing something subtle, rename it so the subtlety is in the name.

03

Decorative section headers

ai-slop/narrative-comment

ASCII banners separating sections of a file. Structure is what folders and filenames are for. If your file needs a banner, your file is too big.

// ─── CLASSIFICATION ───────────────────────────

What to do instead. Split the file. If a file needs banners to stay readable, it probably needs clearer module boundaries. A banner will not save it.

04

Dead code after return

ai-slop/unreachable-code

"Safety" fallbacks emitted after an early return. They can never execute, but they still add noise and make future readers wonder which branch is real.

if (err) return null;
return result;
// fallback
return undefined;

What to do instead. Delete the fallback. A line that cannot run is a line that cannot be tested. Dead code, unused functions, and useless variables should not survive review.

05

Swallowed exceptions

ai-slop/swallowed-exception

A catch block that returns an empty value or does nothing. The agent is making the code compile. It is not handling an error.

try { return await fetchUsers() }
catch { return [] }

What to do instead. Let it throw, or catch the specific error you know about and handle it explicitly. The silent return [] is how you ship an empty dashboard with no idea why.

06

console.log as debugging residue

ai-slop/console-leftover

Agent-assisted debugging can leave console.log calls behind. If nobody checks, they can reach production.

console.log('user:', user)
console.log('before save')

What to do instead. Delete them. Or move to a real logger. Production code does not get narrated to stdout.

07

as any / as unknown as X

ai-slop/unsafe-type-assertion

A common escape hatch. It removes the exact safety TypeScript exists to give you. Every as any is a place where the code needs a real type, a guard, or a narrower API.

const el = document.querySelector('.foo') as unknown as HTMLInputElement

What to do instead. Narrow the type. If it needs a guard, write the guard. If the library types are wrong, declare the missing type in a .d.ts once. Do not paper over it at every call site.

08

Cross-reference commentary

ai-slop/narrative-comment

A comment that explains how two functions coordinate. Tightly coupled to whatever the code looks like today. Rots the moment anything near it changes.

// buildFixRender will then be called with includeHeader: false
// so the header isn't duplicated.
printHeader(state)

What to do instead. Trust the reader. If the coordination is fragile enough that it needs a comment, encode it in a type or a helper.

09

Empty exception handlers with a TODO

ai-slop/swallowed-exception · ai-slop/todo-stub

A catch block with nothing but a TODO in it. It makes the missing behavior visible, but it still leaves the error path unresolved.

catch (err) { /* TODO: handle */ }

What to do instead. Delete the try and let it throw, or handle the error. A TODO in a catch block is not error handling.

10

Generic naming

ai-slop/generic-naming

processData. handleRequest. utils.ts. Agents reach for the generic name when a specific one would tell the reader what is going on. Naming is the cheapest documentation you have. On a good engineering team, this stuff matters.

function processData(data: any): any { ... }

What to do instead. Ask what data, and what processing. The answer is your function name. If you cannot answer, the function is doing too much.

See your score

All ten are detected by aislop. Run aislop rules for the full catalogue. Run the scan below to get a starting point for cleanup.

$ npx aislop scan

Star the AI Slop CLI on GitHub if you want the next release in your feed.