Sold out, but its variations are in stock
The product says out of stock in categories, search and Google, yet its page still sells the variations. One of the two is wrong, and the data can't tell which.
The symptom
A variable product shows “Out of stock” in the category list, in search results and in Google — or it is missing from the category altogether, if the store hides out-of-stock items. Yet open the product page and the variation dropdown works: pick a size, and Add to cart goes through.
It also happens the other way around. The product really is sold out, but its variations still carry stock, so the page takes orders for goods the store does not have.
What it costs
The product page is the only place that reads the variations. Almost everything else reads the product’s own stock status: the stock class themes rely on, the structured data Google gets, and “Hide out of stock items” on category lists, in search and in the Store API.
- Sales nobody sees being lost. Shoppers who browse categories or search never reach the page that would sell to them. The page itself works, so nobody in the store notices anything.
- Search results say unavailable. The structured data on the page tells Google the product is out of stock, whatever the variations say.
- Or orders you cannot ship. When the variations are the wrong half, customers can order stock that is not there — and a canceled order costs more than a missed one.
How to check it yourself
The query below finds published variable products marked out of stock that have at least one enabled variation in stock with a price:
wp db query "SELECT parent.ID, parent.post_title
FROM wp_posts parent
JOIN wp_postmeta ps ON ps.post_id = parent.ID AND ps.meta_key = '_stock_status'
WHERE parent.post_type = 'product' AND parent.post_status = 'publish'
AND ps.meta_value = 'outofstock'
AND EXISTS (SELECT 1 FROM wp_posts v
JOIN wp_postmeta vs ON vs.post_id = v.ID AND vs.meta_key = '_stock_status'
JOIN wp_postmeta vp ON vp.post_id = v.ID AND vp.meta_key = '_price'
WHERE v.post_parent = parent.ID AND v.post_type = 'product_variation'
AND v.post_status = 'publish'
AND vs.meta_value IN ('instock','onbackorder') AND vp.meta_value <> '')"
Treat the result as a first pass. A variation that does not manage its own stock takes the quantity from the product, so with 0 units on the product it cannot be bought, even if its own status still says in stock — the query lists it, a customer could not buy it.
From the admin: Products → Filter by stock status: Out of stock, then open each variable product and compare its Variations tab with the status at the top.
How to fix it
- Decide which status is true. Open the product’s Variations tab and compare the quantities with what you really have.
- If the variations are wrong, correct their stock first. Saving the product before that recalculates its status from the variations and shows the missing goods as available everywhere.
- If the variations are right and the product does not manage stock itself, save the product — WooCommerce recalculates its status from the variations. If it falls back to “Out of stock”, regenerate the product lookup tables (WooCommerce → Status → Tools) and save again.
- If the product manages its own stock at 0 while the variations have their own, saving changes nothing: keep stock on the variations only, or enter the real quantity on the product.
- If the mismatch keeps coming back, something writes stock without going through WooCommerce — an import or a warehouse integration. Fix it there, or the next sync brings it back.
When it is a false positive
Practically never. A product cannot be meant to be sold out and buyable at the same time, so no setting makes this state correct. The one thing to settle before changing anything is which of the two statuses is the real one — that is why the finding shows the quantities.
What keeps this check quiet where it should be quiet: a variation counts only when a customer could actually add it to the cart. A stale “In stock” on a variation that takes its quantity from a product holding 0 units does not produce a finding on its own.
How Merchlint finds it
Merchlint looks at every published variable product whose own stock status is “Out of stock” — across the whole catalog, not only the products that sold, because a product wrongly marked sold out from day one never sells. For each variation it asks WooCommerce the questions WooCommerce asks when adding to the cart: enabled, with a price, in stock, with at least one unit.
The finding shows the product’s status, whether the product manages stock itself, how many variations can be bought out of how many, and a few of them with their quantities — the numbers that tell you which status is the real one.
Confidence: F — fact from the database, with the purchase checks made by WooCommerce itself.
New in version 0.3.5. From the same version, Sold last year, can’t be bought now no longer lists these products, because they can be bought. The opposite case — a product that looks available while none of its variations can be bought — is Every variation is out of stock.
This check runs in the free version, on every product, with no cap.
Doesn't match what you see in your store? Email us — we read every message. contact@merchlint.com