{
"$type": "site.standard.document",
"bskyPostRef": {
"cid": "bafyreiaqxukiwvlazbla5evvi6eljanvbf6us4heahxc5pzaaqz26x2ham",
"uri": "at://did:plc:25rdn5elo5izoxrmtis34zuk/app.bsky.feed.post/3mpd35piem722"
},
"path": "/q00tar00/stop-guessing-why-your-shopify-product-csv-import-failed-d8a",
"publishedAt": "2026-06-28T03:27:18.000Z",
"site": "https://dev.to",
"tags": [
"shopify",
"python",
"cli",
"csv",
"https://github.com/q00tar00/shopify-csv-preflight"
],
"textContent": "You exported a product CSV, edited it in Excel or Google Sheets, and uploaded it to Shopify.\nShopify shows a generic error — or worse, it _silently_ imports the wrong thing: a handle gets\noverwritten, a variant attaches to the wrong product, half your rows go missing. You find out\ndays later from a customer.\n\n**Shopify CSV Preflight Validator** checks the file _before_ you upload it. It runs locally on your\nmachine, never touches your store, needs no API key, and returns three things:\n\n * `fixed_products.csv` — a safe copy with the unambiguous, mechanical mistakes already corrected.\n * `errors.csv` — a machine-readable list of every finding (row, rule, severity, suggested fix).\n * `report.md` — a human-readable report you can read in 30 seconds.\n\n\n\nNo login. No upload of your catalog to a third party. Just a file in, a verdict out.\n\n## Why CSV imports fail (and why the error message doesn't help)\n\nShopify's product CSV import is a two-stage process: it validates the file, then applies rows.\nA file can pass the upload dialog and still misbehave on apply. The most common ways merchants get\nburned:\n\n 1. **A spreadsheet adds a UTF-8 BOM** to the first cell. The first header (`Title`) becomes invisible-garbage + `Title`, so Shopify can't find the title column.\n 2. **Header case / legacy names drift.** `title` instead of `Title`, `Handle` instead of `URL handle`. Some get ignored, some get rejected.\n 3. **A variant row loses its parent handle.** Shopify can't tell which product the variant belongs to.\n 4. **Two product rows share one handle.** Shopify silently keeps one and overwrites/merges the other.\n 5. **Image alt text with no image URL, negative prices, compare-at prices below the real price** — small data bugs that ship to your live storefront.\n\n\n\nThese are not exotic. They're what happens every time a human edits a CSV in a spreadsheet.\n\n## What the tool actually does — a real run\n\nHere is a messy export with several of the problems above. Running:\n\n\n\n csv-preflight check messy-product-import-sample.csv --out-dir ./out --lang en\n\n\nproduces this `report.md` (verbatim):\n\n\n\n # Shopify CSV Preflight Report\n\n - Summary: scanned rows 4 / product groups 3 / 6 critical / 8 warning / 2 auto-fixed (proven) / 1 suggested\n\n ## Critical (fix before import)\n - [F01a] file: UTF-8 BOM detected at file start.\n - [F03a] file: Header 'title' differs only by case from a known column.\n - [R02] row 2: Variant/image row is missing the parent URL handle.\n - [R03] row 1: 2 product-start rows share handle 'aurora-hoodie' (rows 1, 3).\n - [R03] row 3: 2 product-start rows share handle 'aurora-hoodie' (rows 1, 3).\n - [R11] row 4: Image alt text present but image URL is empty.\n\n ## Warning (review recommended)\n - [R07] row 4: inventory_policy 'maybe' is not a documented value (deny/continue).\n - [R08] row 4: Inventory tracker 'shopify' set but inventory quantity is empty/non-numeric.\n - [R10] row 1: Compare-at price 3900.0 <= price 4800.0.\n - [R10] row 4: Price '-1800' is negative.\n - ... (fulfillment-service defaults, etc.)\n\n ## Auto-fixed (proven)\n - [F01a] file: UTF-8 BOM detected at file start.\n - [F03a] file: Header 'title' differs only by case from a known column.\n\n ## Not checked\n - Not checked by this tool: image URL public reachability, handle overwrite/ignore\n against an existing store, metafield product reference resolution, and option position\n consistency with existing products.\n\n\nThe exit code is non-zero when criticals are present, so you can wire it into a script and stop\na bad upload automatically.\n\n### What got fixed automatically\n\nTwo classes of mistake are unambiguous and safe to fix mechanically, so the tool writes them into\n`fixed_products.csv` for you:\n\n * **BOM removed** from the file start.\n * **Header case normalized** (`title` → `Title`).\n\n\n\nEverything else — missing handles, duplicate handles, negative prices — is a _judgment call_ , so the\ntool **reports it but never silently rewrites your data**. You stay in control of your catalog.\n\n### Honest about its limits\n\nThe report always prints a **Not checked** section. The tool reads a file; it does not connect to\nyour store. It cannot know whether an image URL is publicly reachable, whether a handle will\noverwrite an existing product, or whether a metafield reference resolves. It says so, every time.\nWe would rather under-promise than tell you \"import guaranteed\" and be wrong.\n\n## Who this is for\n\n * **Solo merchants** doing a bulk product update before a launch or sale.\n * **Agencies / freelancers** migrating a client's catalog and wanting a clean handoff.\n * **Anyone** who has been burned once by a silent partial import and never wants to guess again.\n\n\n\nIt is **product CSV only**. It deliberately refuses files that look like order or customer exports\n(it detects buyer-PII column names and stops) — your customers' data never goes through it.\n\n## How it compares\n\nThe existing tools (Matrixify, Ablestar) are powerful full migration suites. Merchants who don't\nneed all of that consistently say the same three things: **expensive, slow, and hard to learn.**\n\nThis tool is the opposite end: one command, one purpose — _catch the import-breaking mistakes before\nyou upload_ — with no account and no upload of your catalog.\n\n| Full migration apps | CSV Preflight Validator\n---|---|---\nSetup | Install app, connect store | Run one command locally\nTouches your store | Yes (Admin API) | **No — file in, file out**\nYour catalog leaves your machine | Often | **Never**\nJob | Migrate everything | **Stop a bad import**\n\n## Try it\n\nIt's on GitHub — read the source, grab a release, run it on your own file:\n\n**https://github.com/q00tar00/shopify-csv-preflight**\n\n\n\n uv tool install csv-preflight\n csv-preflight check your-products.csv --out-dir ./out\n\n\nIf a silent partial import has ever bitten you, I'd love to hear what broke — drop a comment or open\nan issue. I'm validating whether this is worth turning into a paid one-shot / Shopify app, and real\nmerchant pain is exactly what I'm looking for.",
"title": "Stop Guessing Why Your Shopify Product CSV Import Failed"
}