Why an attribute stuck in the title holds products back
WooCommerce treats the title as text and attributes as data. Everything that lets a shopper narrow the catalog — filter widgets, variation selectors, comparison tables, structured feeds — reads the data side. A value that lives only in the title is invisible to all of it.
- Filters silently exclude the product. A shopper who filters by Material = Cotton gets every properly tagged tee and none of the ones that merely say “cotton” in their name.
- Variations cannot be built on it. Turning “Shirt — Navy” and “Shirt — White” into one variable product needs Colour as an attribute; as long as it is only in the title, the two stay separate simple products competing with each other.
- Feeds and structured data go out incomplete. Merchant feeds and product schema map from attributes; a colour or size that exists only in the title never reaches them, so the listing is thinner than the product actually is.
- The category becomes inconsistent. When most tees carry Material and a handful do not, the ones without it drop out of comparisons and filters for no reason the shopper can see.
How to find attribute values hiding in titles manually
For a global attribute such as pa_material, this WP-CLI
query lists published products that mention one of its values in the
title but carry no term for that attribute:
wp db query "SELECT p.ID, p.post_title
FROM wp_posts p
WHERE p.post_type = 'product' AND p.post_status = 'publish'
AND p.post_title LIKE '%Cotton%'
AND NOT EXISTS (
SELECT 1
FROM wp_term_relationships tr
JOIN wp_term_taxonomy tt ON tt.term_taxonomy_id = tr.term_taxonomy_id
WHERE tr.object_id = p.ID AND tt.taxonomy = 'pa_material'
)
LIMIT 50;"
Adjust the wp_ prefix if yours differs. Custom
(per-product) attributes are not taxonomy terms; they live serialized
in the _product_attributes row of
wp_postmeta, so this query only covers global attributes.
The gaps are obvious once you run it. You have to repeat it for every
value of every attribute, and a LIKE pattern happily
matches “Cottonwood” or “Cotton” inside an unrelated word. It also
cannot tell you whether the attribute is even expected in that
category, so a plain “Navy” in a title of a paint bucket looks the
same as one on a shirt. And it answers once — the next CSV import can
reintroduce a batch of title-only values without anyone noticing.
How CatalogLift finds and drafts it
The scan reads the store attribute dictionary and current product titles. Values must match consecutive whole words and identify an unambiguous target. Existing assignments are skipped. Values of one or two characters are omitted, regardless of how often an attribute appears elsewhere. A finding names the matched text and the attribute. Category popularity is not part of the rule.
Because this check carries an AI proposal, CatalogLift then drafts the attribute value it spotted — taken from the title and the store's existing attribute values, never invented — and shows it as a before/after diff with the evidence behind it. You approve, adjust or skip; only an approved value is written to WooCommerce, and the next scan verifies the attribute is in place. CatalogLift keeps watching, so a later import that puts a colour back in the title alone shows up as a fresh finding rather than a quiet regression.