Finds and safely removes code that is never executed — unreachable branches, uncalled functions, unused classes, dead feature flags. Use when cleaning up after a feature removal, when the user suspects the codebase has accumulated cruft, or when reducing build/bundle size.
97
96%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Passed
No known issues
Dead code is code that cannot execute under any input. It's not "rarely used" — it's never reachable. The distinction matters: deleting rarely-used code is a product decision; deleting dead code is housekeeping.
| Class | How to prove dead | Confidence |
|---|---|---|
Code after return/throw/exit | Syntactic — compiler/linter catches this | Certain |
| Private function, zero callers | Grep the module. Private = no external callers possible. | Certain |
| Branch with constant-false condition | if False:, if (1 == 2). Constant folding. | Certain |
| Public function, zero callers in repo | Grep. But: reflection, plugins, DI, external callers? | Uncertain — see below |
| Feature flag hard-wired off | if config.NEW_CHECKOUT: and the flag is False everywhere, permanently | High (check all envs first) |
else branch of exhaustive match | All enum values covered above; else can't fire | High (until someone adds an enum value) |
| Zero coverage in tests | Covered-by-nobody. But tests don't cover everything users hit. | Low — absence of test ≠ absence of use |
Static analysis says doThing() has zero callers. Before deleting, check:
getattr(obj, name)(), Class.forName(...), Spring @Component scanning. The call is in a string.__all__, check the public API docs.__getstate__, toJSON(), ORM hooks — called by the framework, not by you.If you can't rule all of these out, it's probably dead but you can't prove dead. Deprecate before delete.
1. Identify → 2. Verify → 3. Deprecate (if public/uncertain) → 4. Delete → 5. Test| Step | Action |
|---|---|
| 1 | Find candidates (static analysis + coverage + grep) |
| 2 | For each: check the uncertainty table above |
| 3 | Uncertain → add a deprecation warning/log, deploy, wait one cycle. Silence = dead. |
| 4 | Delete the code AND its tests AND its imports |
| 5 | Full test suite. Then → behavior-preservation-checker on the containing module. |
Candidate: utils/legacy_format.py — 3 functions, 0% test coverage, no callers found by grep.
Verify:
rg 'legacy_format' --type py → one hit: import utils.legacy_format in utils/__init__.py. Nobody uses the import. Re-exported but unused.setup.py / pyproject.toml [project.scripts] — not there.parse_v1, parse_v2, detect_version — not hook-shaped.Verdict: Dead. But the __init__.py re-export means someone thought it was public. Check git log: last non-formatting commit to legacy_format.py was 3 years ago, message says "migrate to v3 format." The v3 migration finished; v1/v2 parsers are orphaned.
Delete:
__init__.py re-export. Test. Green.utils/legacy_format.py. Test. Green.rg 'legacy_format' one more time — clean.Commit message: Remove dead v1/v2 format parsers — v3 migration completed 2023, no remaining callers.
A flag that's been at one value in every environment for 3+ months is a dead conditional:
if settings.USE_NEW_CHECKOUT:
new_path()
else:
old_path() # ← dead if flag has been True everywhere since Q3Delete the flag check, inline the winning branch, delete the losing branch. Then delete the flag from config. This is the #1 source of dead code in feature-flag-heavy codebases.
else branch just because the if is always true today. If the condition reads external config, "always true" is a current fact, not an invariant.## Dead (certain — delete now)
- <file>:<symbol> — <proof: private+no-callers | after-return | const-false>
Also delete: <tests, imports>
## Probably dead (deprecate first)
- <file>:<symbol> — <why uncertain: might-be-reflected | public-api>
Deprecation: <log line / warning to add>
Revisit after: <one release cycle>
## Not dead (looked dead, isn't)
- <file>:<symbol> — <actual caller you found>47d56bb
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.