Saved, it said, and one row kept the old rate
Set two VAT rates, one of them not a UK rate. The route dropped it, saved the other, and said saved. Found three times in one morning, then made a rule.
Set the VAT rate on two dishes at once: one to 5%, one to 12%. Twelve is not a VAT rate in the UK. Our route dropped it, saved the other dish, and answered that the save had worked. The second dish went on charging 20%, on the screen your VAT return comes off, with nothing anywhere saying so. Twenty lines further down the same file, a comment argued against exactly this behaviour, about the ownership check: refused rather than silently skipped, because a save that quietly matches nothing looks like it worked. One of the two filters on that line had that posture and the other did not.
That was the first of three found in one morning, because once a bug is a shape you go and look for it everywhere.
The same thing, in money and in rotas
The profit and loss budget takes a few lines: sales, cost of goods, labour. Send it sales and labor, the American spelling, or any typo, and it saved sales, left labour where it was, and answered ok. Every variance measured against that budget from then on was wrong, and the screen had said saved.
The availability save in the staff app dropped any day whose answer it did not recognise and wrote the rest. The rota tool's own rule, written two lines under the validator that route calls, is that silence is not a yes: treating an unanswered day as available puts somebody on a shift they never agreed to, and the manager finds out at service. A dropped day is exactly an unanswered day, created by a save the person was told had worked. The change-request route did the same and worse, dropping days outside the requested week, so the request a manager approved was not the request the person made. And the invite route dropped an unknown lock key, which is a lock the inviter believed they had set and the kitchen never got.
The rule was already in the building
None of this was a new lesson. Our tester had found it months earlier, in the permissions screen, where a class named entirely in symbols was reported as created and silently did not exist. The fix there was written out at length: silence is the bug, refusing out loud is the fix. It was learned, documented, and not carried two files sideways. The VAT route was the second to get it, the budget route the third, and the rota and invite routes the fourth, fifth and sixth.
Each now refuses the whole batch and names what was wrong. 12 is not a VAT rate in the UK. Use 20%, 5%, 0%, or leave it unset. Nothing was saved. This board has no labor line. It budgets sales, cogs, labour. Nothing was saved. Leaving a VAT rate unset is still allowed, because nobody has decided is the distinction the whole table is built on, and a stricter check that started refusing it would be worse than the bug.
Not everything that filters is this bug
So that it is not found a seventh time by a customer, there is now a census. Twenty-nine batch writes in the product filter their input, and each is accounted for by one of four words. Refuses: input it does not understand refuses the batch and says why. Replace: a wholesale list replace, where the next render shows exactly what was kept. Narrows: the filter is not user intent at all, it builds a lookup or cleans ids. And skips, once, with the reason in the code: the waste route skips hand-typed money so a mixed basket can still be written off, and the census checks that reason is still there, so the word cannot become a way to classify the bug instead of deciding about it.
A reasoned, stated skip is a decision. An unstated one is a lie about what was saved. For anyone running a venue: a form that discards part of what you typed and tells you it saved is worse than one that fails, because the failure you would have fixed on the spot, and the quiet drop you find on the VAT return.