Table of Contents

Wrong data

Wrong price, wrong stock, missing product. Commerce holds a copy of what the ERP published, so these are nearly always a question about what arrived and when — not about a calculation.

The shape of every one of these tickets

flowchart LR
    ERP["ERP<br/>the source"] --> P["Integration push"]
    P --> DB[("Commerce<br/>database")]
    DB --> C["In-process<br/>cache"]
    DB --> IX["Search<br/>index"]
    C --> UI["What the<br/>customer sees"]
    IX --> UI

    style ERP fill:#eef2ff,stroke:#4f46e5,stroke-width:2px,color:#1e1b4b
    style P fill:#e8f4f9,stroke:#00415a,stroke-width:2px,color:#002230
    style DB fill:#f5f3ff,stroke:#7c3aed,stroke-width:2px,color:#2e1065
    style C fill:#f5f3ff,stroke:#7c3aed,stroke-width:2px,color:#2e1065
    style IX fill:#f5f3ff,stroke:#7c3aed,stroke-width:2px,color:#2e1065
    style UI fill:#fffbeb,stroke:#b45309,stroke-width:2px,color:#451a03

Four places the truth can differ, and they narrow the problem completely:

Compare If they differ Then
ERP vs Commerce database The push has not arrived, or was rejected Upstream. Ask for the push to be re-sent
Database vs what the customer sees A cache, or the search index, is stale Clear the cache, or wait for the index
Both agree, customer still disputes Not a data problem Check what they are comparing against — a quoted price, an old catalogue

Always establish which of these you have before acting. Clearing a cache when the data never arrived wastes the call.

Wrong price

Prices come from pricing rules pushed by the ERP. The usual causes, in order:

A stale rule that should have expired. This is the most common, and it is caused by a real design asymmetry: pricing rules are the one push that does not delete what is absent. Every other feed is a snapshot — send it without a row and the row is removed. Pricing is not. A rule is only retired by giving it an end date.

So a rule the ERP no longer sends is still live in Commerce. If a price looks like an old price, this is almost certainly why.

A missing rule, leaving the product to fall back to a less specific rule or to no price at all. A product with no determinable price cannot be added to a basket.

Quantity breaks. A rule applies from a minimum quantity. A price that "only goes wrong for large orders" is a break doing its job.

Dates. Rules carry validity windows. A price that changed at midnight changed because a window did.

Note

The price a customer pays is not the product's unit price from the catalogue feed. That field is a list price. Pricing rules decide what is charged, and promotions and bonus products can change it again.

Wrong stock

Stock is a snapshot, not a promise. It reflects the last inventory push, and nothing is held until checkout reserves it.

Report Likely cause
Quantity is out of date The push has not run, or the SKU was not in it
A location has vanished Inventory pushes are snapshots — a location absent from a push is removed
Available is lower than expected Reservations. Both in-flight checkouts and placed orders deduct
Stayed low long after checkouts finished A committed reservation — see below

Availability is on hand minus live reservations, so reservations are the usual explanation for a figure that looks too low. Which kind matters:

  • A held reservation belongs to a checkout in progress and expires on its own, after 30 minutes by default. Wait, and it clears.
  • A committed reservation belongs to a placed order and has no expiry. It clears only when the ERP's next stock push says it has absorbed that order — released in the same transaction as the new stock figures.

So availability that stays low points at an order the ERP has not yet acknowledged. That is a question for the ERP feed, not for Commerce, and the reservation is doing its job by holding the line until the push arrives.

Full mechanism, including why the release has to be atomic with the stock update: Inventory lifecycle.

Missing or wrong product

Symptom Cause
Not in the back office either Never pushed. Upstream problem
In the back office, not in search The index has not caught up — wait five minutes. Browse still works
Visible to some customers only Entitlement — see Access
Visible to nobody The blocked flag
A field is empty that was sent Possibly not projected into the index — see below

The search index trap

Search runs against a separate index, populated from a database view by an indexer that runs every five minutes. Two consequences:

A change is not instant. Up to five minutes passes before a corrected product is searchable, so it is right in the database and wrong in search in between. Browse and direct lookup read the database, so a product correct in browse and wrong in search is normal and needs no action.

Some fields never reach the index at all. A column can exist on the product, and be a field in the index, and still be empty on every document — because the view feeding the indexer does not project it. Nothing errors.

Warning

Sleeve length and fabric type are exactly this. Both are accepted, stored, and never indexed. They cannot be searched or filtered on. A ticket asking why filtering by fabric returns nothing is not a bug in the data — the field never arrives.

Clearing a cache

Commerce caches in process, and the back office can clear one named cache or all of them, with hit and miss statistics per cache.

Reach for it when the database is right and the customer sees something else. It is safe — the next request repopulates — but it is not a general fix. If the database is wrong, clearing the cache changes nothing and costs you the time.

Statistics are also a diagnosis in themselves: a cache with almost no hits is not helping, and one with constant invalidations is being written to more than it is read.