Skip to main content
New aislop v0.9.3: rule-precision release. Fewer false positives across docs, imports, eval, wrappers, JSON-LD, and bundled files. Read more →
← Blog
Pattern Guide · 8 min read · reads

The top 10 AI slops we see everywhere

Which AI slop patterns actually matter? Some teams say narrative comments are the worst. Some say it is the swallowed exceptions. Some do not check and just ship. Here is the ranked list we landed on after running aislop against 25 real repos, and the rule that kills 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. Some never check and ship whatever compiles. 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 damage they do. Each one has a rule ID. Each one is deterministic. Your agent produced all of these this week, and you probably shipped a few.

01

Narrative preamble JSDoc

ai-slop/narrative-comment

The multi paragraph JSDoc that restates, in prose, what the function body already says. The single most identifiable AI signature. If a function has a four line comment explaining it, an agent wrote it.

/** * 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 your file is more than 400 lines, your agent is doing something wrong. A banner will not save it.

04

Dead code after return

ai-slop/unreachable-code

"Safety" fallbacks the agent emits after an early return. They can never execute. They outlive the feature. They outlive you.

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, useless variables. Your agents are leaving them behind.

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

Every agent debugging session leaves console.log calls behind. Nobody cleans them up. They ship. Console logs in production, for real.

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

The agent's favorite escape hatch. It removes the exact safety TypeScript exists to give you. Every as any is an agent saying "I could not figure this out so I told the compiler to shut up."

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. The most honest form of slop. The agent knew it was punting. Shipped anyway.

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

What to do instead. Delete the try and let it throw, or handle the error. The TODO has never been handled. It never will be.

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 see how many are hiding in your repo right now. You will not like the number. That is the point.

$ npx aislop scan

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