Milly Software
InsightsEngagementMixed-Availability Products in Shopify Chat: When Some Variants Sell Out
Engagement··6 min read

Mixed-Availability Products in Shopify Chat: When Some Variants Sell Out

How an AI chat widget should handle products where some variants are in stock and others aren't — parent availability, picker UX, and grounding the AI's response in actual stock state.

V
Viet Le
co-founder · Milly Software

A customer asks the chat widget about a phone case. The widget finds the right product. But the product has eight color variants, three of them out of stock. What does the widget say? "Yes, here's the case" would mislead anyone looking for the OOS color. "Sorry, that's unavailable" would lose the sale to the five colors that are in stock. The right answer requires the widget to understand mixed availability, not just a single yes/no.

v2.4.7 added that understanding across the whole stack — product feed, chat handler, ATC default, product card render. This post walks through what was wrong before and what got fixed.

The old behavior: first-variant-as-truth

The pre-v2.4.7 behavior treated the first variant's availability as the parent product's availability. If the first variant was in stock, the product was "available." If the first variant was sold out, the product was "sold out" — even if seven of the other eight variants were in stock. The first-variant-as-truth shortcut worked for single-variant products and broke for everything else.

Three places downstream depended on the parent flag:

  • The chat handler told the AI "this product is OUT OF STOCK" when the parent was OOS
  • ATC defaulted to the first variant — even if that variant was sold out
  • Product cards rendered with a sold-out badge or hid the Add button entirely

The combined effect: a product with seven in-stock variants and one OOS variant could appear unavailable across the widget, depending on which variant Shopify happened to list first. That's a real conversion loss, not an edge case.

Any-variant-available as the parent flag

The fix is one line in the product sync, but it cascades through everything else:

// lib/shopify.ts
parentAvailable: allVariants.some((v) => v.availableForSale)

The parent product is now "available" if any variant is available — not specifically the first one. A product with seven in-stock variants and one OOS variant is available. Only when every variant is sold out does the parent flag flip to OOS. That matches how merchants actually think about whether a product is "in stock," and it matches the experience customers expect from PDPs.

The chat handler now grounds in per-variant truth

Beyond the parent flag, the handler now exposes per-variant availability to the AI:

Variants (numeric ID · name · availability):
  - 41834101211224 · Cloud Blue · in stock
  - 41834101211225 · Rose · OUT OF STOCK
  - 41834101211226 · Olive Bay · in stock
  - 41834101211227 · Desert Sand · OUT OF STOCK

The AI sees this list as part of the system prompt for any product the visitor is currently looking at. When asked about the product, the AI can ground its response: "Cloud Blue and Olive Bay are in stock; Rose and Desert Sand are currently sold out — would you like a back-in-stock alert for one of those?"

Two things follow from this grounding. The AI stops claiming availability it can't verify (the per-variant list is the truth, not the AI's general knowledge). And the AI organically routes to the OOS-subscribe tool when the visitor wanted a sold-out variant — the existence of the BIS path is already in the prompt context.

ATC defaults to the first available variant

The Add to Cart default selection used to be variants[0]. Now it's variants.find(v => v.available). The visitor clicking Add without explicitly picking a variant gets the first in-stock option, not whatever variant happened to be listed first.

For products where every variant is in stock, this is a no-op — first available equals first variant. For mixed- availability products, it's the difference between a successful add and a failed one.

Product cards: OOS variants visible but disabled

On the product cards in chat (and the sticky ATC bar), the full variant grid renders — including the OOS variants. They appear with a strikethrough and disabled click. The visitor sees the complete option landscape and can't accidentally select a sold-out one.

Hiding the OOS variants entirely was tempting (cleaner grid) but the wrong call. Hidden OOS variants make the visitor wonder if the merchant carries that color at all — which could send them comparison-shopping elsewhere instead of just subscribing to the BIS notification. Visible-but-disabled keeps the catalog story honest while keeping the click-paths clean.

These four changes — parent flag, chat grounding, ATC default, card rendering — all flow from the same idea: some variants in, some out isn't a degenerate state. It's the normal state for any catalog with seasonal or size-dependent inventory, and the widget should treat it as such.

Frequently Asked Questions

What happens when a product has some variants in stock and others sold out?

The product stays available as long as any variant is available — it's only marked out of stock when every variant is sold out. The chat grounds its answer in per-variant stock, so it can say something like 'Cloud Blue and Olive Bay are in stock; Rose is currently sold out,' and a product with seven in-stock colors and one sold-out one is never shown as unavailable.

Which variant is added when a shopper clicks Add to Cart without choosing one?

The first in-stock variant, not simply the first variant Shopify happens to list. For a product where every variant is in stock that's the same thing; for a mixed-availability product it's the difference between a successful add and trying to add a sold-out variant.

Does the chat hide sold-out variants?

No. Product cards, and the sticky add-to-cart bar, render the full variant grid including the sold-out options — shown struck through and disabled so they can't be selected. Hiding them would make a shopper wonder whether you carry that color at all; showing them keeps the catalog honest and lets the shopper opt into a back-in-stock alert instead of comparison-shopping elsewhere.

Try Milly Chat

Want to see how this fits your store?
We'll set up a working session.

Get it on ShopifyTalk to sales →