A product feed can be valid CSV and still contain bad product data. Before importing a new export, check for duplicate variant IDs, missing currency codes and unsupported stock values. These are errors you can fix in the exporter while you still know what changed.

Reproduce 3 common failures

Save this synthetic export as feed.csv. The quotes around the titles keep the commas inside each field.

id,title,price,availability,link,image_link shirt-blue-s,"T-Shirt, Blue, S",29.90 EUR,in_stock,https://example.com/shirt-blue-s,https://example.com/shirt-blue-s.jpg shirt-blue-s,"T-Shirt, Blue, M",29.90 EUR,in_stock,https://example.com/shirt-blue-m,https://example.com/shirt-blue-m.jpg shirt-red-m,"T-Shirt, Red, M",29.90,available,https://example.com/shirt-red-m,https://example.com/shirt-red-m.jpg 
  • Rows 2 and 3 reuse the same ID for different sizes. Give each variant a stable ID.
  • Row 4 omits the currency. Export a value such as 29.90 EUR.
  • Row 4 uses available. Map your store's stock values to supported feed values such as in_stock or out_of_stock.

Catch the failures before import

This Python script uses the standard library. Its price check expects a whole number or an amount with two decimal places, followed by a 3-letter currency code. It checks the format only. Merchant Center still validates the currency and target-market requirements.

import csv import re seen_ids = set() availability = {"in_stock", "out_of_stock", "preorder", "backorder"} with open("feed.csv", encoding="utf-8-sig", newline="") as feed: rows = csv.DictReader(feed) for row in rows: variant_id = (row.get("id") or "").strip() price = (row.get("price") or "").strip() stock = (row.get("availability") or "").strip() if not variant_id: print(f"Line {rows.line_num}: missing variant ID") elif variant_id in seen_ids: print(f"Line {rows.line_num}: duplicate ID {variant_id}") seen_ids.add(variant_id) if not re.fullmatch(r"[0-9]+(?:\.[0-9]{2})? [A-Z]{3}", price): print(f"Line {rows.line_num}: expected amount and currency") if stock not in availability: print(f"Line {rows.line_num}: unexpected availability {stock!r}") 

The sample produces three messages: a duplicate ID on line 3, then a missing currency and an unexpected availability value on line 4.

You can also paste the sample into the T&S Google Shopping Feed Check, which reads CSV and TSV locally in the browser. After importing a corrected feed, check Merchant Center's diagnostics and confirm that the price and availability match the exact variant on its landing page.

Google's product data specification lists the supported attributes and their requirements.

This article was drafted with AI assistance. The sample script was run against the CSV above.