The product match was right; the card still made it look wrong
A shopper asked for white, and we found a product that really had a white variant. But its main card image was black. We changed the rule so a variant-only match must be stated in the reply or the card stays off the rail.
The product match was right. The card still made it look wrong.
A shopper asked for white. We found a product that really did have a white variant, so the answer was correct. Then we put the product card underneath it. The card could only show the product's main image, and that image was black. The shopper's next message was "ทำไมส่งสีดำมา" — why did you send me the black one?
We had not retrieved the wrong product. We had shown the right product in a way that made the answer look wrong.
That was the bug.
We had more information than the card could show
The catalogue match happened at the variant level. One of the product's variants was white, which was why the product belonged in the result. The card did not know how to show that distinction. It had one product-level image, and that image happened to show the black version. So the text and the card told two different stories.
Internally, the recommendation made sense: this product had the requested option. On screen, it looked like the assistant had ignored the request and reached for the wrong shirt.
We could have treated that as an image problem, but changing the image was not the lever we actually had. The card was doing what it was built to do: show the product's main photo. The missing piece was in the answer.
We made the answer carry the reason for the match
We changed one rule. If a product matches only through a variant, the reply now has to say that variant out loud. Otherwise, the product stays off the card rail.
That gives the shopper something visible that connects the recommendation to the request. If the answer says the product is available in white, the black main image no longer has to explain the whole match by itself. The text carries the piece the card cannot show. If the reply does not mention the matching variant, we do not show the card.
We did not change search ranking. We did not ask the model to become more conservative. We did not decide that the product itself was a bad match. The match was already right. We changed the point where a correct internal result became a shopper-facing recommendation.
We stopped treating the card as decoration
This bug was easy to miss if we checked only the generated sentence. The sentence was grounded. The product existed. The requested variant existed. On those checks alone, the turn passed. The shopper still thought it was wrong.
That forced a more useful definition of the answer: the answer is not only the text the model writes. It is the text plus the product object we put beside it. When those two disagree visually, the shopper gets two answers at once.
The text says white. The card says black.
The card usually wins because it is the thing being shown as evidence. That means a product card has to agree with the claim it supports. Correct retrieval is not enough if the presentation hides the reason that retrieval was correct.
Variant-level truth does not automatically fit product-level UI
A catalogue can know more than a card can display. Products have variants. A simple card has one main image. That gap is structural, and adding more retrieval logic does not close it.
We chose not to pretend otherwise. We did not rewrite the product image to resemble the matched variant. We did not infer that the main photo represented every option. We made the reply state the information we actually had: this product matched because of a particular variant.
That is a smaller change than building a variant-aware card, but it fixes the contradiction the shopper saw. It also gives us a clear rule to check later: whenever a recommendation depends on information the card cannot display, the reply has to carry that information itself.
The answer was right before the experience was right
This case did not involve a hallucinated product, stale stock, or a bad catalogue search. We had the right product. We had the right reason. We still produced a bad recommendation experience because we failed to show that reason. The shopper caught it immediately.
That is why this bug mattered more than the size of the code change suggests. A shopping assistant does not earn trust from the facts it holds internally. The visible answer has to make those facts make sense together.
For this case, the fix was simple: when the match exists only at the variant level, we say so. If we cannot say why the card belongs there, we do not show the card.