Issue reference
Your product data has no price block
- SCHEMA_OFFER_MISSING
- See the price
- —
- High
What it means
tragent reports this at the “See the price” stage. The question there is “Can it see what the product costs?” Price and currency have to be stated in a way that matches what a shopper is shown.
What it does to an agent
Most agents fail at this point. The few that find a way round it spend more time and model calls doing so, and may give up before checkout.
The Offer is the part of the markup that says the product can be bought: its price, its currency and its stock. A Product without an Offer reads to an agent as a catalogue entry, not something for sale, and agents filtering for buyable items skip it.
tragent reports this as high when no product on the page has an Offer, and as a warning when only some do. A ProductGroup's variants may carry the offers instead of the group; tragent reads them there.
How to fix it
Add an Offer with price, priceCurrency and availability. Without it an agent cannot tell whether the item is buyable.
"offers": {
"@type": "Offer",
"price": "89.00",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"url": "https://shop.example/products/trail-runner-2"
}On your platform
Shopify
The structured_data filter adds offers for each variant. A missing Offer usually means a hand-written block in the theme; replace it with the filter.
{%- comment -%} sections/main-product.liquid {%- endcomment -%}
<script type="application/ld+json">
{{ product | structured_data }}
</script>WooCommerce
WooCommerce leaves the Offer out when a product has no price, which is common for variable products where only variations are priced and for products set to "call for price". Price every purchasable product, or variation, in the admin.
Headless or custom
Emit one Offer per purchasable variant, or an AggregateOffer with lowPrice and highPrice when a page covers several.
In practice
Every variant a shopper can buy should have an Offer. For a product in several sizes and colours, that means an Offer per variant, each with its own price, availability and URL, ideally with the variant selected in the URL. An agent asked for a specific size uses that URL to land on the right variant, rather than on the default one.
Products you show but do not sell online, such as in-store only or call for price, should not carry an Offer with an empty or zero price. Leave the Offer out and say on the page how to buy; an agent will then send the shopper there rather than trying to check out something that cannot be bought.
Set the Offer's url to the product page itself, with the variant selected where your platform supports it, and its seller to your organisation if you also sell through marketplaces. An agent that finds the same product offered by several sellers uses the seller and url to send the shopper to the right place, and an Offer without them can be credited to the wrong one.
Check the fix
- Confirm the JSON-LD on a product page has offers with a price and currency.
- Run the scan; See the price and Check stock should both score.
Run the check that reported SCHEMA_OFFER_MISSING again after the change. The scan needs no account; an issue found during an AI shopping test needs that test run again.
npx @tragent/cli scan https://your-store.comCommon mistakes
- An Offer with no price, which counts as unpriced.
- offers as a plain number rather than an Offer object.