False Reuse
Context
Section titled “Context”You’re extracting code from a single caller into a separate unit (function, class, service), primarily for legibility or testability — not because it has an intrinsic contract or multiple consumers.
Cost type
Section titled “Cost type”Primarily cognitive, borne by other humans who read the code and infer a contract that wasn’t intended. The cost is small or zero in solo-LLM-collaborated regimes; existential in teams.
What goes wrong
Section titled “What goes wrong”- Other developers read the extraction as a published API and depend on it from elsewhere, coupling features that weren’t meant to be coupled.
- Tests at the new boundary become the canonical correctness specification, displacing the boundary tests that actually verify the feature works (see also Displaced Truth).
- Future changes to the original caller are constrained by the new “public” surface, even though no one outside that caller needs the contract (see also Sticky Contract).
Prospective indicators
Section titled “Prospective indicators”- The extracted unit lives in a
shared/orcommon/folder by default. - You’re writing tests for the new unit before any second caller exists.
- The extracted unit’s name describes a generic capability (
UserService) rather than its actual role (UserPagePresenter). - You’re tempted to write a JSDoc/TSDoc block for “future consumers.”
Retrospective indicators
Section titled “Retrospective indicators”- The unit has multiple callers across features but no documented contract or owner.
- Test coverage of the unit is high, but production bugs in the features that use it are still common.
- Refactoring the original caller requires re-reasoning about the unit’s other consumers.
- Multiple slightly different versions of the same logic exist because consumers worked around a contract that didn’t quite fit.
Prevention
Section titled “Prevention”- Place internal extractions inside the feature folder. Enforce with module-boundary tooling (Sheriff, ESLint
no-restricted-imports). - Name the unit for its role in the caller, not for its capability.
UserPagePresenterreads as scaffolding;UserServicereads as published. - Don’t write tests at the new boundary unless the boundary itself has a contract worth verifying.
- Don’t move the unit to a shared location until at least one second consumer arrives and the contract has been understood and named.
When this isn’t a failure mode
Section titled “When this isn’t a failure mode”- The extracted code has an intrinsic contract — Luhn check, date parser, parser for an external format, financial calculation, crypto primitive. The contract pre-exists the caller. Programming-product testing discipline applies, even inside a single application.
- You explicitly intend the extraction to be reused, you’re prepared to pay the programming-product costs, and you’re documenting the contract.
- Solo work, AI-collaborated, low-stakes: there’s no other developer to misread the extraction, so the social-misreading harm doesn’t apply. The behavioral failure modes (Sticky Contract, Displaced Truth) may still apply.