DEV Community

Cover image for When a user reports 1 bug, there are always more (the grep that broke my assumptions)
Michel Faure
Michel Faure

Posted on • Originally published at dev.to

When a user reports 1 bug, there are always more (the grep that broke my assumptions)

The night one student's record taught me to stop looking at the record

A Tuesday in May 2026, around 10 p.m. Catherine pings me from Maisons-Laffitte: « ça bug sur Loubna, c'est vite corrigé. » Sentry opens. Cannot read properties of undefined on the function that renders a weekly attendance sheet. The child has no last name on file. My hand is already typing the one-line UPDATE that would write Sebti into the nom column and close the ticket in eight seconds.

I don't type the UPDATE. I type a wider query, because another record taught me a month earlier that the record is never the problem.

SELECT statut, COUNT(*) FROM contacts
WHERE statut = 'inscrit'
  AND ((nom IS NULL OR nom = '') OR (prenom IS NULL OR prenom = ''));
-- → 16
Enter fullscreen mode Exit fullscreen mode

Sixteen, not one. Two rows fully empty, fourteen with a missing first name inherited from a legacy Airtable import where one column never mapped, and the one Catherine had just watched crash. Had I patched the record, fifteen other attendance sheets would have fallen over the following weeks, each one reported as an isolated incident, each one patched as an exception, each one leaving the dormant class waiting quietly for the next.

The reflex you have to defuse

When a user reports a bug, what they hand you is not a description of the problem. It is a probe seed, a pathological case that crossed their cognitive filter on its way to your Slack. Its apparent rarity is an artefact of their observation channel, not a property of the system. Catherine sees what crashes under her fingers in Maisons-Laffitte; she does not see the fifteen dormant rows on the other ateliers that will crash three weeks from now.

The correct first move is not the git diff on the record. It is the GROUP BY that asks the system how many rows share the same pathology. Ninety seconds of material probing, and the nature of the fix changes radically.

Why an AI agent makes this worse

When the nominative patch costs eight seconds to generate, the apparent marginal cost of skipping the probe drops to zero. The agent will not suggest you map the class. It knows how to answer the question you asked, and the question your prompt encoded was "fix this record", not "chart every record in this state". The old human friction that forced you to weigh whether the effort was worth it for one case vanishes with the agent. You have to rematerialise it by discipline.

I did not change my agent. I changed my opening prompt. When a production bug surfaces, my first message never says "fix this record". It says "write the GROUP BY query that reveals the full class of similar cases in the database." The fix comes after, once the class is mapped. If the probe returns only one case — it happens — the commit says so explicitly, probe pattern: 1/1, as proof the question was asked.

Three questions before any fix

Whatever you think of your senior instinct, ask the three, and ask them in order. What is the class this case is an instance of, expressed as a SQL predicate or a grep regex, not as intuition? How many instances does the class hold in production, right now, as you read the ticket? Does the proposed fix address the class, or only the reported instance? If the third answer is only the instance, you do not have a fix, you have a dated palliative. The class is still waiting.


The widening reflex has a name in the Counterpart Toolkit, *Widen before correcting, sibling to Falsify before fix: github.com/michelfaure/doctrine-counterpart*

Top comments (0)