Every caller has to check whether things actually worked, because this code returns status codes instead of throwing exceptions. The defensive ifs cascade...
A Curated Catalog of Code Smells
Every named code smell in one place — classified, connected, and fixable.
Companion to peer-reviewed research published by Springer NatureAlternative Classes with Different Interfaces
aka Duplicate Abstraction
Two classes. Same job. Different spelling. One says hug_zombie(), the other says hug_snowman(), and neither realizes they're duplicating logic behind method...
Base Class depends on Subclass
aka Base Classes Depending on Their Derivatives
When a parent class reaches down to reference its own children, the inheritance tree grows upside down. Change a leaf, redeploy the trunk.
If a method has "and" or "or" in its name, it's confessing to doing two things, and that confession is an invitation to split it in half.
Does filter(true) mean take or drop? When a function operates on raw booleans, it destroys the information about what those values represent. The type...
Callback Hell
aka Hierarchy of Callbacks, Pyramid of Doom
Nested callbacks indented so deep the closing brackets cascade like a staircase to nowhere. The actual logic hides somewhere around indent level five.
Code that works but makes you feel stupid for not understanding it. Reinvented built-ins, abused language quirks, logic compacted into one-liners that...
Dozens of methods that do almost the same thing, each differing by one small detail. Add a new feature and the count multiplies again. Good luck remembering...
Reading it feels like solving a discrete math problem. The if-statement just checks whether a timer expired, but between the negations and conjunctions,...
A regex pattern so dense it needs an online decomposer to parse. Named variables and a builder function would make the same expression self-documenting.
Conditional Complexity
aka Repeated Switching, Switch Statement +1 more
The if/else chain that grows a new branch with every feature. First it's readable. Then it's manageable. Then it's a 200-line switch statement, and suddenly...
red, green, and blue passed separately to every function that needs a color. The same variables travel together everywhere, never packaged into the object...
You read past it wondering if it's safe to delete. Unreachable branches, commented-out blocks, functions that last ran in 2019. They cost nothing at runtime...
A class that changes for database reasons on Monday, calculation reasons on Wednesday, and display reasons on Friday. Same file, different reasons, and the...
Dubious Abstraction
aka Inconsistent Abstraction Levels, Functions Should Descend Only One Level of Abstraction +2 more
A method that orchestrates a business workflow but also opens its own database connection, mixing strategy with plumbing until you can't tell what level of...
Duplicated Code
aka Clones, Code Clone +3 more
The same logic in five places. Change one, miss another, and watch the behavior quietly diverge. According to Fowler, this is the single worst smell in a...
Fallacious Comment
aka Comment, Attribute Signature and Comment are Opposite +1 more
A comment that was true once but now lies. The code changed, the comment didn't, and there's no linter that catches the drift.
Fallacious Method Name
aka "Set" Method returns, "Get" Method does not Return +7 more
getItems() returns a single item. isValid() returns a string. setValue() quietly returns a value too. Method names that betray every convention programmers...
Fate over Action
aka Data Class
A class that holds data but owns none of the behavior operating on it. External code reaches in, pulls values out, and makes decisions the object never...
A method that touches another class's fields more than its own. It was written in the wrong place and belongs closer to the data it can't stop reaching for.
Flag Argument
aka Boolean in Method Parameter
A boolean parameter that forces the caller to write book(marcel, false) — and everyone who reads it to wonder: false what?
Global Data
aka Global Variables
Any code, anywhere, can read and write these variables. When something breaks, every function in the codebase is a suspect.
The class works perfectly in the developer's environment and crashes in production. You read the stack trace, search every constructor, and find nothing....
Imperative Loops
aka Explicitly Indexed Loops, Indexed Loops +1 more
for(i=0; i<len; i++) — the ceremony of manually tracking indexes, accumulating results, and handling off-by-one errors, when a map, filter, or built-in says...
Inappropriate Static
aka Static Cling
Impossible to override. Painful to mock. Silently coupling everything that calls them. Static methods are convenient right up until the behavior needs to...
A third-party library that does 95% of what you need. The missing 5% means building workarounds that duplicate effort, drift from the original, and never...
Inconsistent Names
aka Use Standard Nomenclature Where Possible
The mental shortcuts that let developers navigate by pattern break when one class calls it store(), another says add(), and a third insists on put(). Same...
Inconsistent Style
aka Sequence Inconsistency
Mixed formatting, flipped parameter orders, and clashing conventions in the same codebase. The code works, but the inconsistency saps trust. If they...
Indecent Exposure
aka Excessive Exposure
Everything's public. Nothing's hidden. Other modules couple to implementation details they were never meant to see, and now you can't change a private...
Insider Trading
aka Inappropriate Intimacy
Two classes exchanging private implementation details they shouldn't have access to — the kind of under-the-table knowledge sharing that makes either one...
Large Class
aka Blob, Brain Class +5 more
The God Class. Too many methods, too many fields, too many reasons to exist. Reading it takes a morning, testing it takes a sprint, and changing it is a...
Lazy Element
aka Lazy Class
The meeting that could have been an email — except it's a class. One field, one method that just delegates to another, an abstraction that costs more in...
Long Method
aka Complex Method, God Method +1 more
A method so long you scroll past the beginning before reaching the end. Every change requires re-reading the whole thing, every piece of logic is trapped...
Five arguments. Six. Seven. At some point the function signature becomes a riddle, the caller needs a cheat sheet, and the method is clearly trying to do...
Magic Number
aka Uncommunicative Number
A bare 86400 in the code — is that seconds in a day, a timeout, or a config limit? Unnamed numbers hide intent, and when the same literal appears in five...
object.getA().getB().getC().getD() — the caller knows the entire relationship chain, and every intermediate link becomes a dependency that breaks when any...
Half its methods just call the same method on another class. It exists, it delegates, and its author can't explain what it adds. Remove it, and nothing breaks.
Data that anything can modify at any time. The bug reproduces instantly in production and vanishes in your debugger — by the time you pause execution,...
Defensive null checks scattered everywhere like a nervous tic — each one a band-aid over a missing Null Object, and each a reminder that Tony Hoare called...
You stare at the function for five minutes before realizing it calculates overtime pay. Between the single-letter variables, the magic numbers, and the...
Oddball Solution
aka Inconsistent Solution
Same problem, two solutions, different files. One uses an adapter, the other rolls its own socket logic, and you can't tell which approach is the correct...
Add a BasicUser, and you need a BasicFunctions. Add a PremiumUser, and here comes PremiumFunctions. Every subclass in one hierarchy demands a mirror in the...
A phone number stored as a string. A price stored as a float. Concepts that deserve their own types get crammed into primitives, losing validation,...
Refused Bequest
aka Refused Parent Bequest
A Tower that extends Minion but throws NotImplemented on move(). The inheritance contract promises full support; the subclass delivers a runtime exception...
Close the socket when you're done. Check the environment variables before you start. Reset the state after every call. The object could handle all of this...
Shotgun Surgery
aka Solution Sprawl
One small feature change. A dozen files to edit. You submit the PR, then find two more files you missed.
Side Effects
aka Impure Functions
set_gold(amount) sounds simple enough. Except it also triggers a dancing animation and resets the payday timer. Methods that do more than their name...
Special Case
aka Complex Conditional
The if-statement that handles "one weird edge case" before the real logic begins. It was a hotfix once. It was never properly refactored. Now every future...
An abstract base class for a hierarchy that never grew. Three extra parameters for a feature you were sure someone would request. Abstractions built for a...
found = False. Then a loop. Then found = True somewhere inside. Then a check after. Mutable flags that complicate control flow when a direct return or a...
A field that's null eleven months of the year and suddenly matters during one specific calculation. The object carries it everywhere, for one brief moment...
Data hitchhiking through a chain of methods that never use it. Each function accepts the parameter, ignores it, and passes it along — just so the one at the...
Type Embedded in Name
aka Attribute Name and Attributes Type are Opposite
playerName, dateString, userList: the type is already in the annotation, and now it's in the name too. Redundant today, misleading tomorrow when the type...
Uncommunicative Name
aka Mysterious Name, Function Names Should Say What They Do +2 more
data, val, m1, temp, get_f(). The code compiles fine. Understanding it requires reverse-engineering every abbreviation the original author thought was...
Vertical Separation
aka Regions
Variables declared at the top of a method, used fifty lines later. By the time you reach the logic that needs them, you've already forgotten what half the...
"What" Comment
aka Comment
Comments that narrate what the code does instead of why — a deodorant sprayed over smelly code, where extracting a well-named method would eliminate both...