This is a submission for DEV's Summer Bug Smash: Smash Stories powered by Sentry.
Two bugs, one story. A parser that failed on every real call, plus the test that certified
it as working for two review rounds. The second one is the one worth reading about.
I was writing adapters for a protocol indexer. Each adapter has a Receipt parser: it
receives the on-chain state changes from one transaction and produces a structured
outcome, "this account swapped 100 of token A for 98 of token B". Downstream consumers
trust that outcome. If the parser picks the wrong movement out of the transaction, the
system reports a swap that never happened, with no error anywhere.
The tests ran against live mainnet, which is where this starts.
The end-to-end test for one adapter looked roughly like this:
if (halted) {
expect(index).toBe(1) // the call reverted on chain, fine
} else {
expect(result).toEqual(...) // the call succeeded, check the payload
}
The reasoning was sensible. This is a live chain, the contract call might legitimately
revert depending on pool state, so the test tolerates a revert instead of failing the
build on someone else's liquidity.
Read it again. There is no input that makes this test fail. Success gets checked.
Failure gets accepted. The assertion has no opinion.
Nine cases against Monad mainnet, all green, through two rounds of review. What they were
actually reporting was my own parser throwing on every single call. The halt the test
tolerated was never the chain rejecting anything. It was my code.
The reviewer did not catch it. I did not catch it. The suite was green, which is what
we both looked at.
With the tolerance removed the real bug surfaced immediately, a one-liner of
the worst kind:
const leg = transfers.find(t => /* right endpoints, right amount, not our own token */)
.find()
returns the first match. The predicate described a shape that any ERC-20
transfer of the right size could satisfy. So in a transaction carrying two structurally
identical movements, the parser reported whichever came first in the log.
Two ways that goes wrong. I reproduced both:
Neither raises anything. You get a plausible, wrong answer.
The fix is a rule rather than a patch: filter
the candidates, then require exactly one. Zero keeps the existing missing-evidence error. Two or more throws and names the
The parser bug is ordinary. .find()
where you meant "the only one" is a mistake every
codebase has. Once you see it you fix it in a minute.
The test bug is the interesting one, because it consumed the evidence I was using to judge the parser. A green suite is what I hand a reviewer. A branch in the assertion
Three things I now do because of it.
Any if (failure) {...} else {...} in a test is unverified until probed. So is any
Grep for first-match selection. .find(
, [0]
, .at(0)
, .shift()
. For each one,
ask what stops a second, equally valid item from matching. If the predicate cannot name
something fixed, it is guessing.
Prove the new assertion fails without the fix. Be careful how you undo it. This
one bit me a second time. To show an assertion catches the bug you revert the source and
run the suite. I used git checkout -- <file>
to undo the experiment, but that file also
held the round's real work, so my new assertions vanished and the next run went green for
an entirely different reason. Caught by diffing the working tree, not by the suite. So:
toggle only the file the experiment needs, never one carrying the change, then capture the
failing output to a file the moment it fails, because you cannot reproduce it once the
state is restored.
Neither of these was a crash. Nothing threw, nothing logged, no monitor fired. One
produced a wrong answer that looked like a right answer. The other produced a green
test that looked like a passing test.
That is the class of bug I have started looking for first, because it is the class that
survives review. A crash gets fixed the day it happens. A confident wrong answer ships,
and then it gets built on.
Written with AI assistance (Claude, Anthropic). The bugs, the reproductions and the review history are from my own work on a real open source adapter. Both defects were reproduced from both directions, the decoy and the duplicate, before the fix was submitted. The corrected assertions were confirmed failing against the unpatched parser.