Cancel It, Annotate It, Never Unlink It

An invalid bug was cancelled and then unlinked from its story. The sprint's linked-bug count went from 102 to 101, and the only record that testing ever pushed back went with it.

An invalid bug got cancelled. That was the right call.

Then somebody deleted its link to the story.

That second action is the one worth an article, because it looks like the same act of tidying and it is not.

What Actually Disappeared

The bug still exists. You can open it, read the steps, see who cancelled it and when. Nothing was destroyed inside the record.

The relationship is what got tidied away.

And the relationship was the evidence. The sprint's linked-bug count dropped from 102 to 101 — one row of arithmetic, barely visible. But the story now carries no trace that testing ever raised anything against it. Open its history and it reads as a clean pass. No pushback, no ambiguity, no moment where somebody looked at the build and said this is not what I expected.

The bug survived. The fact that it was ever about that story did not.

An Invalid Bug Is a Coordinate

Here is the part that gets lost when "invalid" is treated as "worthless".

A bug that turns out to be invalid marks a precise point where the specification and a tester's mental model diverged. The tester read the available artefacts, built an expectation, exercised the system, and got something else. One of those two was wrong. For the value of the record, it does not matter which.

What matters is that somebody has now located, to the exact scenario, a place where the written material and a competent reader's understanding do not produce the same answer.

That is expensive information. It costs a full investigation cycle to generate — setup, reproduction, triage, developer time, a decision. Almost nothing else QA produces points that accurately at the gap between what a document says and what it makes people believe.

Cancelling the finding does not consume that information. Unlinking it does.

The Pattern That Now Lives in Someone's Memory

There were two bugs. They were raised together and they formed a pattern between them — the same misreading applied twice, in two places, by the same route.

One of them lost its link. The pair stopped being a pair.

The remaining bug is still there, still readable, and now looks like a one-off. The second data point exists but no longer sits anywhere near the first. Whether that pattern gets recognised again depends entirely on whether the person who saw it is still on the project and still remembers.

That is the mechanism to hold on to. Individual records survive unlinking; relationships between records do not. And on a project of any size, the relationships are where most of the useful signal lives — this bug against that story, this pair together, this cluster in one area of the build.

Cancellation and Unlinking Are Different Statements

They get done in the same five seconds by the same person, so they feel like one gesture. They say completely different things.

Cancellation is a statement about the finding: this is not a defect. It is a judgement, it is reversible, and it leaves a trail.

Unlinking is a statement about history: this never had anything to do with that story. It is not a judgement about the bug at all. It is an edit to the record of what happened.

The first is triage. The second is revision.

What To Do Instead

Four habits, none of which take longer than the deletion would have.

  • Write the cancellation reason inside the record, not in a chat thread. One sentence explaining what the tester expected and why the system was right anyway. That sentence is the whole value of the artefact and it is the first thing lost when the reason lives in a conversation.
  • Use a resolution category that separates the kinds of invalid. "Not a defect — spec read differently" is a documentation signal. "Not a defect — environment data" is an environment signal. Collapsing both into "cancelled" throws away the distinction that would let you count them.
  • Leave every link in place, including on cancelled records. If the link is only there to be counted, you have already decided the count matters more than the history. It does not.
  • Count invalid bugs as their own line, deliberately. A story with several cancelled bugs against it is not a clean story. It is a story whose specification was ambiguous enough to mislead a trained reader more than once, and that is worth knowing before it goes to a customer-facing release.

Why This Keeps Happening

Nobody unlinks a bug out of malice. They unlink it because a number somewhere is being read as a quality score, and a cancelled bug attached to a story makes the story look worse than it was.

That reasoning is backwards, and it is worth saying plainly.

If bugs-per-story is being read in a way that punishes accurate history, the reading is the defect. The response is to fix how the number is interpreted, or to exclude cancelled records at the reporting layer where the exclusion is visible and reversible. Not to edit the underlying relationships, which is the one place where the change is silent and permanent.

Reporting filters can be changed back. Deleted links cannot, because six months later nobody remembers that there was ever a link to restore.

The Line I Now Apply

Anything that alters what the record says happened requires a reason written down at the moment it is done. Anything that only alters what a report displays does not.

Cancelling a bug falls in the second category. Unlinking it falls in the first, and it is almost never worth the price.

How many cancelled bugs on your current project are still attached to the story that produced them — and if they are not, who remembers why they were raised?