On April 28, 2026, we fixed a one-line setting that had been wrong since 2023: EDIT_DATABASE was still false.
The symptom was blunt. Comments on an admin details page would not save. The ticket that came in as WORK-6880 described exactly that. No intermittent error. No strange edge case. Just a form that accepted input and failed to persist it.
The fix itself was not interesting:
EDIT_DATABASE=trueWhat made it worth writing down was where that line came from. The work had resumed on an old branch. Three years earlier, while we were working ticket WORK-4596, someone had flipped EDIT_DATABASE for debugging. That was a sensible local move. The mistake was not restoring the switch when that earlier work was done. The branch sat with its debugging state intact, then later became the starting point for a production change.
We shipped the details-page fix on April 24. Four days later, the comments were still not saving because the old guard was still active. The problem was not the new code. It was a piece of scaffolding that had survived long enough to look normal.
The diagnostic path was shorter than the history
The first observation pointed us at the write path. The page received the comment, but the database did not get it. That narrowed the problem from the page as a whole to the condition that permits an edit.
The relevant endpoint was an old Classic ASP details handler. The behavior looked like a bad save routine at first because the visible failure was a missing record. It was not. The handler was deliberately configured not to edit the database.
EDIT_DATABASE=falseThat line explained the whole failure. There was no database migration to repair. No malformed payload. No concurrency problem. No permission change. The application was following the configuration it had been given.
The evidence in the branch history then changed the diagnosis from “why does this page not save?” to “why did a debugging control from 2023 reach a 2026 release?” The answer was mundane and more dangerous than a novel bug: we resumed old work without rechecking the surrounding scaffolding.
We considered the wrong fixes first
The failing symptom made several options look plausible. We could have inspected the comment schema, traced the form request, or treated the write operation as a regression in the new change. Those would have been reasonable next steps if the endpoint had been attempting a write.
I did start down one of those paths. A second ticket, about an upgrade dialog on a different admin page, had also stopped doing anything, and I had noted it as possibly related. So the plan for the session was to check whether both came from one shared regression. The first thing I read was the change that had just landed on the details handler, which had switched a try/catch back on. It looked like a strong candidate, until I saw it could only hide an error, not cause a missing save. Then I opened the page, saved a test comment and read the response. The server said the comment had been updated, and the SQL was printed as text in the body instead of being run. There was no error to hide, so I left the other dialog out of this fix.
They lost once we found EDIT_DATABASE=false. Tracing deeper would only have proven that a disabled write path did not write. Changing the schema would have been unrelated. Patching the new code would have created a second layer of behavior around a switch that was supposed to be restored.
The correct repair was to restore the intended production setting:
EDIT_DATABASE=trueThat is the entire code change. The larger change is procedural.
An old branch is not neutral ground
We added a resumed-branch scaffolding audit to our learnings after this incident. It is not a ceremonial code review pass. It is a targeted search for conditions that were useful when the branch was active and unsafe once the branch is back in production work.
For a branch like this, the audit starts at the edges of normal execution: edit guards, feature flags, development-only constants, temporary error handling, stubbed integrations, and conditions that suppress writes. We compare those controls with the current ticket before we assume the branch is a safe base.
The important part is the sequence. We do this before treating the existing branch behavior as a baseline. If we start from the assumption that all surrounding code is intentional, a three-year-old debug choice becomes invisible. It inherits legitimacy just because it is already there.
There are alternatives. We could require a fresh branch for every change and abandon old branches entirely. That would prevent this particular inheritance, but it would also discard useful in-progress work and does not protect us from old debug state in long-lived shared code. We could lean on ordinary review. We do review, but ordinary review is usually focused on the diff. The flag that hurt us was not new. It was precisely the kind of unchanged context a diff does not force anyone to revisit.
A resumed branch needs a different assumption: it contains historical intent until proven otherwise. The branch may still hold valuable work. It may also hold a debug switch from 2023 that silently turns off a production write in 2026.
This one cost us four days between ship and repair. The next audit starts with the scaffolding, not the feature.