Invalid sale prices in WooCommerce

A sale price that is negative, unreadable, or not actually below the regular price turns a discount into a mistake the shopper can see. CatalogLift finds every simple product carrying one — with both prices as evidence — and lets you correct it without leaving the finding.

Sales-readiness High severity Fix in CatalogLift

Why a broken sale price costs you sales

WooCommerce treats the sale price as the price. When it is set, the storefront strikes through the regular price and charges the sale value at checkout, whether or not that value makes sense. A sale price that is negative, has a stray character, or a number equal to or above the regular price does not fail quietly; it renders.

  • The discount reads backwards. A struck-through regular price next to a higher sale price looks like a pricing error, and shoppers do not buy from stores that look careless with money.
  • A free promotion is a separate decision. A sale price of 0 below a positive regular price is a valid 100% discount. CatalogLift asks you to review it under the discount threshold check, without treating it as a broken sale price.
  • Feeds and ads reject the product. Google Merchant Center and other feed consumers validate that the sale price is below the regular price and disapprove items that fail, so the product drops out of shopping campaigns while the mistake stands.
  • Nobody sees it in wp-admin. The product list shows the effective price, not the pair; a sale price that is one cent above the regular price hides in plain sight until a customer points it out.

How to find invalid sale prices manually

Both prices live in postmeta. With WP-CLI, one query lists published simple products whose sale price is set but not a non-negative number below the regular price:

wp db query "SELECT p.ID, p.post_title,
       r.meta_value AS regular_price, s.meta_value AS sale_price
FROM wp_posts p
JOIN wp_postmeta s ON s.post_id = p.ID AND s.meta_key = '_sale_price'
LEFT JOIN wp_postmeta r ON r.post_id = p.ID AND r.meta_key = '_regular_price'
WHERE p.post_type = 'product' AND p.post_status = 'publish'
  AND s.meta_value <> ''
  AND (
    s.meta_value NOT REGEXP '^[0-9]+([.][0-9]+)?$'
    OR CAST(s.meta_value AS DECIMAL(18,6)) < 0
    OR CAST(s.meta_value AS DECIMAL(18,6)) >= CAST(r.meta_value AS DECIMAL(18,6))
  )
ORDER BY p.ID;"

Adjust the table prefix if yours isn't wp_. The regular expression rejects negative numbers and stray characters before the casts run.

This works — with gaps. It does not separate simple products from variable parents, whose price meta is derived from their variations, so the list needs a second pass against wp_term_relationships to keep only the simple ones. It says nothing about why each row is there — a comma decimal, a negative amount and a price above the regular one all look the same in the output. And it is a snapshot: the next CSV import or price sync can write a fresh broken sale price the day after you cleaned the list.

How CatalogLift finds and fixes it

Every scan reads the regular and sale price of each published simple product in the synced catalog. A product with no sale price is left alone. A product whose sale price is set but is not a readable decimal at least zero, or is equal to or higher than the regular price, is flagged at high severity, with the field, the regular price and the sale price attached as evidence — so you see the exact pair that collides, not just a product name.

The fix stays inside CatalogLift and involves no AI. From the finding you clear the sale price or type the corrected one, review the before/after diff, and approve. Nothing changes in the store before that decision; on it, the change goes to WooCommerce and the next scan verifies the sale price is now valid, and because CatalogLift keeps watching, an import that reintroduces the same mistake becomes a fresh finding rather than a silent regression.

Fair questions, straight answers.

What counts as an invalid sale price?

A sale price that is set but cannot be charged: negative or not a readable decimal — or one that is equal to or higher than the regular price. A product with no sale price at all is fine; only a sale price that is present and broken is flagged.

Does WooCommerce not block this on its own?

The product editor warns when you type a sale price above the regular price, but CSV imports, REST API updates, bulk edits and plugins write straight to postmeta and skip that check. Once the value is in, the storefront shows whatever it finds.

Does CatalogLift fix the sale price for me?

This is one of the checks you fix inside CatalogLift without AI. The finding shows the regular and sale price side by side; you clear the sale price or type the corrected one, approve the change, and CatalogLift writes it to WooCommerce. The next scan verifies it landed.

Are variable products covered?

This check reads simple products. Variations carry their own prices and are covered by the variation price checks, which have their own findings.

See it on your own catalog.

Create a free account, connect your WooCommerce store and this check runs on your real products, along with the rest.

No card required. The free plan never writes to WooCommerce.