A segfault that wasn't a bug, and the API I finally deleted
This app was later renamed Deep Cut Atlas. It’s called “Discoverer” throughout below, because that’s what it was called on the day this happened.
This was supposed to be the easy cleanup issue. A repo review had flagged a handful of things in Discoverer’s MusicKit service layer: a few methods nobody called anymore, two error types that showed ugly default messages instead of real copy, some duplicated matching logic, and a couple of playlist lookups doing more work than they needed to. None of it was a functional bug. All of it was the kind of small debt that just needed someone to actually go delete it.
The dead code was oddly satisfying to remove. Four methods, zero callers, confirmed by grep before I touched anything. One parameter that was always passed the same hardcoded value at every call site, which meant an entire branch of code behind it had never run outside of the one place it was actually needed. Deleting code that provably does nothing is one of the few refactors that feels completely safe, because you’re not guessing about behavior, you’re just removing a path nothing takes.
Then I ran the test suite and every single test failed instantly. Not “the tests I touched.” All of them, unrelated ones included - string helpers, array chunking utilities, things that had nothing to do with my change. Each one reported a runtime of zero seconds, which is the tell that something crashed the whole test process rather than any individual test actually failing.
The crash log pointed at a real memory access violation inside a completely different function than the one I’d been editing, and the calling function it named doesn’t actually call that function anywhere in the current code. That mismatch - a named caller that couldn’t possibly call the named callee - is what made me suspicious instead of just trying to fix a phantom bug. Removing methods from a shared interface changes the underlying memory layout of how those calls get dispatched, and an incremental build can end up gluing together compiled pieces from before and after the change. The result runs, but it jumps to the wrong place while the debugger still shows you the old labels.
A full clean and rebuild fixed it instantly, no code changes. That’s the whole trick: when you’ve just changed what methods exist on something, and the very next test run segfaults in a way that makes no sense, don’t start debugging the named function. Clean first.
The rest of the cleanup landed the way cleanups should: quietly. Two error types now say something a person would actually understand instead of a raw enum case number. A duplicated string-matching block became one shared, tested helper. Two playlist lookups that used to fetch every playlist and scan for the one they wanted now ask for that one directly. None of it changes what the app does. All of it makes the next person’s job smaller.
Related reading
Seven small Deep Cut Atlas fixes, and a test I almost deleted
A backlog sweep smallest-first: ScaledMetric artwork, a wrong thumbs icon, dead chevrons - and a broken test whose comment described a race my fix had narrowed but not closed.
The suggestions bug that survived because my own investigation lied to me twice
A frozen snapshot, a plausible 'History is safe' claim that fell apart under a skeptical second pass, and the coalescing layer I almost built that already existed one layer down.
The bug I filed was wrong, and the fixture that fixed it broke four other tests
A write-time guard for a bug that couldn't happen, the read-time exclusion that was actually wanted, and four tests quietly load-bearing on a fixture count.