Skip to content
Development

A doc-drift fix that wasn't as boring as it sounded

By Victor Da Luz
railsrubydev-logblog-manager

Today’s task was three items pulled from an earlier audit: a stale line in a docs file, a couple of placeholder config values that never got replaced with real ones, and a wrong claim in a different repo’s inventory file. On paper, none of it sounded interesting. In practice, almost every step of it turned into something worth stopping for.

Verify before you plan

Before writing any code I checked each of the three claims against the actual current state, instead of trusting the issue text. Good thing - one of the three (“the build still runs on GitHub-hosted infrastructure”) turned out to be mostly already fixed by earlier work, except for a single line in a different section of the same file that the earlier fix had missed. If I’d just executed the issue as written, I’d have either duplicated a fix or missed the one line that still needed it.

The password reset that was quietly dead

One of the placeholder values was a mailer’s default host and from-address, both still set to a dummy domain. Before touching them I checked whether the feature behind them was even real - and it was: a working password-reset controller action, fully wired up, just pointed at nothing. Fixing the placeholder was the easy part. The harder question was scope: should I also go set up real outgoing mail delivery? I decided no - that’s a bigger, separate piece of work - and left an explicit comment saying so, rather than quietly leaving a half-fixed feature with no explanation.

What review caught that I didn’t

I ran a review pass on the small diff before merging, mostly as a formality given how little code was actually changing. It found real things.

The domain I’d picked for the “from” address had no mail records configured at all - no SPF, no DKIM, nothing. Any email sent from it would get flagged as spam or rejected outright by anything modern. The codebase already had a real, working mail domain in use elsewhere; I’d just reached for the wrong one out of habit.

More interesting: the host value I set for generating links in emails was correct for production, but this app runs the exact same environment file for both production and staging - there’s no separate staging config. So a password-reset email sent from staging would have generated a link pointing at production. Currently harmless, because mail delivery isn’t configured yet, but it would have become a real, silent bug the moment someone finished that follow-up work later - and by then nobody would think to check a line from an unrelated “fix the docs” issue.

Fixed it by reading the host from an environment variable set per deploy target, instead of hardcoding one value. Before trusting that the fix actually worked, I called the deploy tool’s config-loading code directly and printed what each destination resolves to - confirmed different values for production and staging without needing to deploy first. Cheap check, caught a possible typo before it became a live problem.

Going where the trail led

The cross-repo piece was a one-line inventory fix. While pushing it, I hit a red CI check on that repo’s main branch and paused instead of pushing anyway. Turned out it wasn’t a real failure - the job had run for three seconds and recorded zero steps, which is the signature of the billing-related outage I’d already diagnosed in a different project. Confirmed there was no actual problem by running the same lint check locally myself. Filed a follow-up issue to fix the underlying cause there too, since it’s the same category of “CI looks green or red for reasons that have nothing to do with your code” risk.

What’s next

Nothing pending here. The theme across the whole session: small, “boring” issues are exactly the ones worth slowing down on, because nobody expects to find anything and that’s precisely when things get missed.

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