Wrong logical connector
An and where an or belongs.
What it looks like
- A guard with two conditions where flipping the connector changes only the rare case.
- A negation that did not distribute:
!(a && b)becoming!a && !b. - A condition rewritten 'for clarity' during a refactor.
Why it survives review
When both operands agree — both true or both false — && and || give the same answer, and in most real inputs they do agree. The two only diverge when the operands disagree, which is the case nobody was thinking about when they wrote the condition or the test.
How to see it
- Build the truth table. Two conditions is four rows; write them out rather than reasoning about them.
- For a guard, ask specifically about the row where one side is true and the other false, and decide what should happen there.
- De Morgan's law is where negation refactors go wrong:
!(a && b)is!a || !b, never!a && !b.
A minimal pair
Correct
if (start === undefined || end === undefined) return null;
Defective
if (start === undefined && end === undefined) return null;
With only end missing, the correct build returns null and the defective one carries on with undefined.
Practise it
5 diffs in the corpus carry this class. They are not listed, because knowing which diff contains what would make finding it a comprehension question about this page.
Go to the exercises