Symptom

Hooks, abstract base classes, configuration knobs, and parameters added 'in case the team needs them' — but no real call site uses them.

Goal

The code expresses exactly what it does today — abstraction earns its keep when a real second user shows up.

Smellier version

class Strategy { execute() {} }
class OnlyStrategy extends Strategy { execute() { /* the real one */ } }
new OnlyStrategy().execute();

Fresher version

function execute() {
// the real one
}
execute();
Example source: Illustrative example written for this site, not a quotation from any source.
Pressure

Tests are forced to cover branches no one exercises; readers learn a vocabulary they don't need; YAGNI debt compounds.

Tradeoff

Removing the unused abstraction can break a real (if rare) future need; YAGNI is a useful default, but historical context sometimes justifies the option-value.

Relief

Smaller surface, fewer concepts, fewer test branches.

Trap

Aggressive removal of every unused hook on principle — including ones that document a known coming feature or a stable boundary the team agreed to preserve.