What brokeUpdated 3 October 2026
Brand matching picked the wrong brand, and matched inside words
A full code review on 2026-07-02 found that the function mapping scanned bottle text to a brand mistook "Tanqueray No. Ten" for Tanqueray London Dry and "Star of Bombay" for Bombay Sapphire, and that the short key "oss" matched inside other words. The fix made the function prefer the longest key and respect word boundaries, and 18 test cases now cover it.
The short version
What went wrongThe matching function mapped "Tanqueray No. Ten" to Tanqueray London Dry, "Star of Bombay" to Bombay Sapphire, and the key "oss" matched inside other words.
How we found itA full code review on 2 July 2026 found it among five bugs.
The rule nowMatch text against keys using the longest key and word boundaries, and test short keys, substring keys and keys inside unrelated words.
This post documents something Claude got wrong. The claim rests on a commit or a file, not on memory. All of Claude's mistakes
One of our apps suggests serves for a given gin brand. You can type a brand name or photograph a bottle. During a full code review on 2 July 2026, we found that the photo path sometimes landed on the wrong brand.
This post covers what was wrong, how it was found, and the rule that came out of it.
How scanning works
Scanning has two steps.
First, a vision model gets the photo along with a closed list of known brand names. It is told to pick exactly one name from the list, or to answer with a fixed “unknown” word if nothing matches.
Second, a matching function takes the text the model returned and turns it into a brand in the app’s data. That second step had the bug.
What went wrong
The progress log for that day gives three concrete examples:
- “Tanqueray No. Ten” came out as Tanqueray London Dry.
- “Star of Bombay” came out as Bombay Sapphire.
- The short key “oss” matched inside other words. The log gives “Cross …” as the example.
The commit message sums up both the fix and the bug in one line: longest key plus word boundaries, because No. Ten and Star of Bombay hit the wrong brand and “oss” hit inside words.
The material doesn’t show the old implementation line by line. The fix makes the function prefer the longest matching key and respect word boundaries.
This kind of bug is easy to miss. You get a plausible but wrong answer.
Who got it wrong
Henning writes no code himself, so the original matching function was Claude’s, and so was this flaw. The commit lists the matching problem under “Bugs” in a broad review. The changelog file came later (it says the app got it on 31 August 2026) and says nothing about this.
The material doesn’t name who did the review, so we don’t name anyone there.
How it was found
The progress log calls the work a “full code review focused on bugs and a more professional UI/UX”. The matching bug was one of five bugs fixed in the same commit. The others:
- The prompt with the closed brand list was built once when the server started. Brands added inside the app could never be recognised by a scan. The prompt is now built for each request from the built-in brands plus the custom ones.
- Large phone photos could exceed the upload limit. Images are now scaled down in the browser before upload, to at most 1280 pixels and JPEG.
- The form for adding a brand had no styling at all.
- The shopping list broke on a brand without a signature serve, and the recipe status didn’t say when a search came up empty.
The same commit also switched the server-side lookup to a variant that matches against built-in and custom brands together. That fits the prompt fix: if the model can now name a custom brand, the matcher has to be able to find it.
How the fix was checked
The commit lists three kinds of verification:
- 18 test cases for the matching function
- a production build
- an end-to-end run in Playwright with 14 checks
The material doesn’t list the 18 cases one by one. The three examples above are the ones the log names, and they are exactly the edge cases a test set for this function needs: a longer product name containing a shorter brand name, and a short key that shows up inside other words.
The test count is from the commit on 2026-07-02. We haven’t re-run or recounted it for this post.
What we take from it
Matching free text against a list of names looks trivial, and that’s the problem. A matcher that neither prefers the longest key nor respects word boundaries works on the easy cases you try first. It fails on the cases that matter in a brand list: product lines that share a name, and short keys that are also common letter sequences.
The bug sat in the plain string handling after the model step. When a pipeline has a model step and a deterministic step, the deterministic step needs its own tests. It doesn’t get them for free because the model step looks fine.
The rule
Text matching against a list of keys must pick the longest matching key and respect word boundaries. Edge cases go into tests before the function counts as done: short keys, keys that are substrings of other keys, and keys that occur inside unrelated words.
Corrections
- Attribution corrected: an earlier version said the material did not show who wrote the code and did not put the mistake on Claude. Henning writes no code himself; the code was written by Claude.