Code Smells Catalog Skip to content

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 Nature

Every caller has to check whether things actually worked, because this code returns status codes instead of throwing exceptions. The defensive ifs cascade...

1 2 Jerzyk, 2023

Two classes. Same job. Different spelling. One says hug_zombie(), the other says hug_snowman(), and neither realizes they're duplicating logic behind method...

1 2 Fowler, 1999

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.

0 1 Martin, 2008

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.

1 3 Jerzyk, 2023

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...

1 3 Jerzyk, 2023

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.

3 1 Jerzyk, 2023

Code that works but makes you feel stupid for not understanding it. Reinvented built-ins, abused language quirks, logic compacted into one-liners that...

2 3 Jerzyk, 2023

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...

2 2 Wake, 2004

Reading it feels like solving a discrete math problem. The if-statement just checks whether a timer expired, but between the negations and conjunctions,...

3 4 Wake, 2004

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.

2 3 Jerzyk, 2023

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...

6 6 Smith, 2013

red, green, and blue passed separately to every function that needs a color. The same variables travel together everywhere, never packaged into the object...

2 1 Fowler, 1999

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...

1 1 Wake, 2004

A class that changes for database reasons on Monday, calculation reasons on Wednesday, and display reasons on Friday. Same file, different reasons, and the...

5 1 Fowler, 1999

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...

3 8 Jerzyk, 2023

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...

5 6 Fowler, 1999

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.

1 3 Jerzyk, 2023

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...

1 2 Jerzyk, 2023

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...

3 4 Jerzyk, 2023

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.

3 2 Fowler, 1999

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?

2 7 Martin, 2008

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.

1 6 Fowler, 2018

The class works perfectly in the developer's environment and crashes in production. You read the stack trace, search every constructor, and find nothing....

1 3 Smith, 2013

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...

2 5 Jerzyk, 2023

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...

1 1 Martin, 2008

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...

2 2 Fowler, 1999

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...

1 1 Wake, 2004

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...

2 1 Jerzyk, 2023

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...

6 4 Kerievsky, 2005

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...

5 2 Fowler, 1999

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...

5 4 Fowler, 1999

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...

3 3 Fowler, 1999

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...

6 6 Fowler, 1999

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...

5 6 Fowler, 1999

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...

2 5 Wake, 2004

object.getA().getB().getC().getD() — the caller knows the entire relationship chain, and every intermediate link becomes a dependency that breaks when any...

3 6 Fowler, 1999

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.

4 3 Fowler, 1999

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,...

8 2 Fowler, 2018

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...

3 4 Wake, 2004

You stare at the function for five minutes before realizing it calculates overtime pay. Between the single-letter variables, the magic numbers, and the...

1 8 Martin, 2008

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...

1 4 Kerievsky, 2005

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...

4 3 Fowler, 1999

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,...

7 3 Fowler, 1999

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...

5 1 Fowler, 1999

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...

2 4 Smith, 2013

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.

6 4 Fowler, 1999

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...

2 4 Jerzyk, 2023

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...

4 2 Wake, 2004

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...

4 3 Fowler, 1999

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...

3 6 Jerzyk, 2023

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...

3 4 Fowler, 1999

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...

3 4 Smith, 2013

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...

3 3 Wake, 2004

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...

3 5 Wake, 2004

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...

1 1 Martin, 2008

"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...

3 7 Jerzyk, 2023