Why a variation needs its own GTIN
GS1 assigns a GTIN per trade item, and to a warehouse, a barcode scanner or a shopping feed, the small blue shirt and the large red one are different trade items. WooCommerce gives every variation its own GTIN, UPC, EAN, or ISBN field for exactly this reason — and leaves it empty until someone fills it, with nothing inherited from the parent.
- Google rejects variants sharing a code. Merchant Center treats the GTIN as the identity of the offer. Two variants submitted with the same code claim to be the same product, and Google responds by disapproving offers rather than guessing which one is real. A parent's code copied across its variations is the fastest way to manufacture that conflict.
- An empty field runs at limited performance. A variant without any code is not disapproved, but it matches poorly: Google can't connect it to the known product, so the offer gets fewer placements and weaker comparison matching.
- Marketplaces list variants by their codes. Marketplaces require a valid barcode per offer, and comparison engines match on brand, manufacturer code and barcode. Variants without their own codes either can't list or all point at the same comparison row.
- The barcode on the box already knows. Suppliers print a distinct code on every variant's packaging. When your store carries none of them, receiving, returns and any scan-based workflow fall back to guessing by name.
How to find variations without a GTIN manually
Variations are rows in wp_posts with the type
product_variation, and each keeps its code in
wp_postmeta under _global_unique_id on its
own row. This WP-CLI query lists published variations of published
products whose field is missing or empty, next to the parent's code:
wp db query "SELECT v.ID, p.post_title AS parent, pg.meta_value AS parent_gtin FROM wp_posts v JOIN wp_posts p ON p.ID = v.post_parent AND p.post_type = 'product' AND p.post_status = 'publish' LEFT JOIN wp_postmeta vg ON vg.post_id = v.ID AND vg.meta_key = '_global_unique_id' LEFT JOIN wp_postmeta pg ON pg.post_id = p.ID AND pg.meta_key = '_global_unique_id' WHERE v.post_type = 'product_variation' AND v.post_status = 'publish' AND (vg.meta_value IS NULL OR vg.meta_value = '') ORDER BY p.post_title, v.ID LIMIT 50;"
Adjust the table prefix if yours isn't wp_. The
parent_gtin column shows what the parent carries — a
temptation, not a fallback: never copy it onto the variations.
The query names variations by ID, so someone still has to open each one to learn which size and colour it is, then chase the right code through supplier sheets or the physical packaging. And the answer holds for one moment: the next import of a variable product with blank variation codes starts the list over.
How CatalogLift finds it
Every scan walks the published variations of published variable products in the synced catalog and reads each variation's own identifier field as it came from WooCommerce. A variation whose field is missing or empty becomes a finding at medium severity, with the parent product's title and the variation's option values spelled out as evidence, so you know whether you are looking at the small blue or the large red without opening wp-admin.
There is no AI on this path, and no code is ever suggested — not from the parent, not from a sibling, not from a pattern. A derived or drafted GTIN with a valid checksum would sail through validation while identifying the wrong product, which is worse than an empty field. You look up each variant's real code, type it inside CatalogLift and approve it. Nothing is written before that decision; on it, CatalogLift writes the code to WooCommerce and the next scan verifies each variation carries its own. Because CatalogLift keeps watching, an import that adds variations without codes shows up as a fresh finding instead of a quiet regression, and the first scan costs nothing and needs no card.