Asterix Project All articles
Developer Experience

Nine Years, One Ticket: What a Zombie Issue Teaches Us About Project Debt

Asterix Project
Nine Years, One Ticket: What a Zombie Issue Teaches Us About Project Debt

Every mature open-source repository has one. Not the most-starred feature request, not the flaky CI job that pages someone every third Tuesday — the issue. The one that predates the current build system, references dependencies that no longer exist, and carries a comment count in the hundreds. It stays open because closing it feels like an admission, and fixing it has never quite risen to the top of anyone's sprint.

We spent several weeks reading through one such ticket in a widely deployed serialization library — a bug report opened in the spring of 2016 by a developer who noticed that certain Unicode edge cases were silently mangled on round-trip. Nine years later, the issue remains open. What follows is an anatomy of how that happened, and what it quietly charged the project along the way.

The First Eighteen Months: When It Still Mattered

The original report was, by any standard, excellent. A minimal reproduction, expected versus actual behavior, environment details, even a failing test case attached as a gist. The first maintainer response came within hours: confirmed, triaged as P2, assigned a milestone.

Then the milestone slipped. It slipped again the following quarter, and by month fourteen the milestone field had been quietly removed — a small administrative erasure that, in practice, communicated more than any comment. Contributors who had planned work around the fix moved on. One submitted a patch that sat unreviewed for five months before the author closed their own pull request with a terse "rebasing this is no longer worth it to me."

That lost patch is the first hidden cost of a zombie issue. It is rarely the only one.

The Workaround Economy

By year three, the issue had stopped functioning as a bug tracker and started functioning as infrastructure. Downstream projects discovered it the way sailors discover reefs: by hitting it. A Rust binding pinned an older version specifically to avoid the corruption. A data pipeline at a midwestern health analytics firm (described at length in comment #217) implemented a preprocessing shim that escaped the problematic code points before they reached the library.

Count them across the thread and you find at least eleven distinct workarounds, each one an undocumented tax paid in engineering hours. None of them appear in the project's documentation. All of them will break the day someone finally ships a fix that changes behavior — which is its own migration problem, inherited directly from the years of delay.

The 'Me Too' Tax

Around year four, the comment section metastasized. +1 reactions, duplicate reports linked and unlinked, questions from newcomers asking whether the issue was still relevant. Each notification pings every subscriber. Veteran maintainers describe muting long-lived issues as a survival mechanism, but muting means the signal — a genuinely new reproduction case, a fresh offer to help — gets buried with the noise.

This is expectation management failing in both directions at once. Newcomers read 380 comments of inactivity and conclude the project is dead. Maintainers read 380 comments and feel ambushed by the weight of a decision they deferred so long ago that its original context is gone.

Why Good Teams Leave Tickets Open for a Decade

It is tempting to frame zombie issues as negligence. In practice they persist for structural reasons:

The last point is the decisive one. Stale issues are rarely triage failures. They are governance failures — decisions with no designated decision-maker.

What We'd Recommend

Projects that handle long-lived issues well tend to share a few practices. They run a periodic staleness audit — an annual pass where every issue older than a fixed horizon gets an explicit disposition: fixed, planned, or closed with a written rationale. They treat "closed as not planned" as a legitimate, documented outcome rather than a defeat, pointing affected users to a known-workaround note in the docs. And they cap the 'me too' tax with reaction-based feedback instead of comments.

None of this requires new tooling. It requires someone with the standing to say, on the record, "we are not going to fix this, and here is why" — or "we are, and here is when."

The Ledger

Add it up and the nine-year ticket cost the project one abandoned contribution, eleven scattered workarounds, hundreds of maintainer hours in duplicate triage, and a measurable amount of reputational goodwill from developers who equate a stale tracker with a stale codebase. The fix itself might have taken a focused week.

An issue tracker is a promise ledger. Every open ticket is a promise the project has made, implicitly, to everyone who starred it. Keeping that ledger honest — even when the honest entry reads "no" — is one of the cheapest trust investments a project can make. Asterix Project's own contributor guide says it plainly: a closed issue with a clear reason serves the community better than an open one serving as a graveyard. Nine years is long enough to prove the point.

All Articles

Related Articles

Where Do Decisions Go to Die? Auditing the Graveyards of Open-Source Governance

Where Do Decisions Go to Die? Auditing the Graveyards of Open-Source Governance

Democracy Has a Latency Budget: Accounting for the Real Price of Public Decision-Making

Democracy Has a Latency Budget: Accounting for the Real Price of Public Decision-Making

Stable Is a Contract, Not a Mood: Rethinking How Projects Signal Readiness

Stable Is a Contract, Not a Mood: Rethinking How Projects Signal Readiness