Skip to content
Development

Deleting dead code, and catching a wrong reason for a right answer

By Victor Da Luz
railsrubydev-logblog-manager

Small one today: a cleanup issue for leftovers from a Medium integration I ripped out weeks ago (blog-manager now publishes to Medium through Postiz, not a native flow). The issue listed four things to delete - a CORS initializer, a browser extension, a rake task, and three gems - with a stated reason for each. I don’t usually second-guess an issue I wrote myself. This time I did anyway, and I’m glad.

What I built

Deleted config/initializers/cors.rb (wildcard CORS scoped to a route that no longer exists), the extension/ browser extension (hardcoded that same dead route), lib/tasks/medium.rake, and three now-unused gems from the Gemfile. Straightforward.

What surprised me

The issue said the rake task should go because it “targets the removed webhook.” I opened the file to confirm before deleting it, and it doesn’t mention the webhook at all. It’s three tasks for backfilling Medium syndication state and hero images from production snapshots - a completely different concern. So why delete it?

I checked what it actually calls: two service classes, Medium::PublishedBackfill and Medium::HeroImageBackfill. Neither exists anymore. They were deleted weeks ago in the same PR that dropped every medium_* database column, as part of the original Medium removal. Whoever wrote this rake task’s deletion note (me, evidently, in a rush) got the conclusion right and the reasoning wrong. The task really is dead - just not for the stated reason. Every one of its three tasks would raise a NameError the moment you ran it.

That distinction matters more than it looks like at first glance. If I’d taken the stated reason at face value and moved on, I’d have deleted the file without noticing that a second, unrelated piece of functionality (backfilling syndication state from a production snapshot) had already silently rotted. It happened to be dead too, so no harm this time. But “the stated reason is wrong” and “the conclusion is also wrong” are different failure modes, and only checking the second one costs you nothing extra once you’re already reading the file.

The issue also asked me to clean up stale Medium references in the README, CLAUDE.md, and docs. I grepped first. There weren’t any - every mention left in those files accurately describes the Postiz-based flow that’s still live. Another place where the task list and reality had quietly diverged since I wrote it.

Then code review on the PR caught one more thing I’d missed entirely: an orphaned credential. The extension authenticated to its webhook with a shared secret, stored in the encrypted credentials file. Nothing referenced it anymore, but I hadn’t thought to check credentials when I was thinking about code and gems. Pruned it too, using a small non-interactive script instead of the usual credentials:edit flow, specifically so the decrypted value never touched a terminal or a log.

What’s next

Nothing dramatic - the backlog has a few more small hardening items in a similar spirit. But I’m making a note to myself: when an issue states a reason for an action, read enough of the code to verify the reason, not just enough to confirm the action. They usually match. When they don’t, it’s worth knowing why before you trust the next “obviously correct” line item.

Related reading

Development

The editor commit button is a deploy button

Committing a draft to main auto-deploys the blog. Once that clicked, sync-vs-async stopped being a style question - plus the legacy-affiliate carve-out a new validator almost broke.

Read