<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: q00tar00</title>
    <description>The latest articles on DEV Community by q00tar00 (@q00tar00).</description>
    <link>https://dev.to/q00tar00</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4006005%2Fd5c6c192-1bab-4009-96c6-851394a8cb58.png</url>
      <title>DEV Community: q00tar00</title>
      <link>https://dev.to/q00tar00</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/q00tar00"/>
    <language>en</language>
    <item>
      <title>Stop Guessing Why Your Shopify Product CSV Import Failed</title>
      <dc:creator>q00tar00</dc:creator>
      <pubDate>Sun, 28 Jun 2026 03:27:18 +0000</pubDate>
      <link>https://dev.to/q00tar00/stop-guessing-why-your-shopify-product-csv-import-failed-d8a</link>
      <guid>https://dev.to/q00tar00/stop-guessing-why-your-shopify-product-csv-import-failed-d8a</guid>
      <description>&lt;p&gt;You exported a product CSV, edited it in Excel or Google Sheets, and uploaded it to Shopify.&lt;br&gt;
Shopify shows a generic error — or worse, it &lt;em&gt;silently&lt;/em&gt; imports the wrong thing: a handle gets&lt;br&gt;
overwritten, a variant attaches to the wrong product, half your rows go missing. You find out&lt;br&gt;
days later from a customer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shopify CSV Preflight Validator&lt;/strong&gt; checks the file &lt;em&gt;before&lt;/em&gt; you upload it. It runs locally on your&lt;br&gt;
machine, never touches your store, needs no API key, and returns three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;fixed_products.csv&lt;/code&gt; — a safe copy with the unambiguous, mechanical mistakes already corrected.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;errors.csv&lt;/code&gt; — a machine-readable list of every finding (row, rule, severity, suggested fix).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;report.md&lt;/code&gt; — a human-readable report you can read in 30 seconds.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No login. No upload of your catalog to a third party. Just a file in, a verdict out.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why CSV imports fail (and why the error message doesn't help)
&lt;/h2&gt;

&lt;p&gt;Shopify's product CSV import is a two-stage process: it validates the file, then applies rows.&lt;br&gt;
A file can pass the upload dialog and still misbehave on apply. The most common ways merchants get&lt;br&gt;
burned:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;A spreadsheet adds a UTF-8 BOM&lt;/strong&gt; to the first cell. The first header (&lt;code&gt;Title&lt;/code&gt;) becomes
invisible-garbage + &lt;code&gt;Title&lt;/code&gt;, so Shopify can't find the title column.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Header case / legacy names drift.&lt;/strong&gt; &lt;code&gt;title&lt;/code&gt; instead of &lt;code&gt;Title&lt;/code&gt;, &lt;code&gt;Handle&lt;/code&gt; instead of &lt;code&gt;URL handle&lt;/code&gt;.
Some get ignored, some get rejected.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A variant row loses its parent handle.&lt;/strong&gt; Shopify can't tell which product the variant belongs to.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Two product rows share one handle.&lt;/strong&gt; Shopify silently keeps one and overwrites/merges the other.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Image alt text with no image URL, negative prices, compare-at prices below the real price&lt;/strong&gt; —
small data bugs that ship to your live storefront.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These are not exotic. They're what happens every time a human edits a CSV in a spreadsheet.&lt;/p&gt;
&lt;h2&gt;
  
  
  What the tool actually does — a real run
&lt;/h2&gt;

&lt;p&gt;Here is a messy export with several of the problems above. Running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;csv-preflight check messy-product-import-sample.csv &lt;span class="nt"&gt;--out-dir&lt;/span&gt; ./out &lt;span class="nt"&gt;--lang&lt;/span&gt; en
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;produces this &lt;code&gt;report.md&lt;/code&gt; (verbatim):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Shopify CSV Preflight Report

- Summary: scanned rows 4 / product groups 3 / 6 critical / 8 warning / 2 auto-fixed (proven) / 1 suggested

## Critical (fix before import)
- [F01a] file: UTF-8 BOM detected at file start.
- [F03a] file: Header 'title' differs only by case from a known column.
- [R02] row 2: Variant/image row is missing the parent URL handle.
- [R03] row 1: 2 product-start rows share handle 'aurora-hoodie' (rows 1, 3).
- [R03] row 3: 2 product-start rows share handle 'aurora-hoodie' (rows 1, 3).
- [R11] row 4: Image alt text present but image URL is empty.

## Warning (review recommended)
- [R07] row 4: inventory_policy 'maybe' is not a documented value (deny/continue).
- [R08] row 4: Inventory tracker 'shopify' set but inventory quantity is empty/non-numeric.
- [R10] row 1: Compare-at price 3900.0 &amp;lt;= price 4800.0.
- [R10] row 4: Price '-1800' is negative.
- ... (fulfillment-service defaults, etc.)

## Auto-fixed (proven)
- [F01a] file: UTF-8 BOM detected at file start.
- [F03a] file: Header 'title' differs only by case from a known column.

## Not checked
- Not checked by this tool: image URL public reachability, handle overwrite/ignore
  against an existing store, metafield product reference resolution, and option position
  consistency with existing products.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exit code is non-zero when criticals are present, so you can wire it into a script and stop&lt;br&gt;
a bad upload automatically.&lt;/p&gt;
&lt;h3&gt;
  
  
  What got fixed automatically
&lt;/h3&gt;

&lt;p&gt;Two classes of mistake are unambiguous and safe to fix mechanically, so the tool writes them into&lt;br&gt;
&lt;code&gt;fixed_products.csv&lt;/code&gt; for you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;BOM removed&lt;/strong&gt; from the file start.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Header case normalized&lt;/strong&gt; (&lt;code&gt;title&lt;/code&gt; → &lt;code&gt;Title&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything else — missing handles, duplicate handles, negative prices — is a &lt;em&gt;judgment call&lt;/em&gt;, so the&lt;br&gt;
tool &lt;strong&gt;reports it but never silently rewrites your data&lt;/strong&gt;. You stay in control of your catalog.&lt;/p&gt;
&lt;h3&gt;
  
  
  Honest about its limits
&lt;/h3&gt;

&lt;p&gt;The report always prints a &lt;strong&gt;Not checked&lt;/strong&gt; section. The tool reads a file; it does not connect to&lt;br&gt;
your store. It cannot know whether an image URL is publicly reachable, whether a handle will&lt;br&gt;
overwrite an existing product, or whether a metafield reference resolves. It says so, every time.&lt;br&gt;
We would rather under-promise than tell you "import guaranteed" and be wrong.&lt;/p&gt;
&lt;h2&gt;
  
  
  Who this is for
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Solo merchants&lt;/strong&gt; doing a bulk product update before a launch or sale.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agencies / freelancers&lt;/strong&gt; migrating a client's catalog and wanting a clean handoff.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anyone&lt;/strong&gt; who has been burned once by a silent partial import and never wants to guess again.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is &lt;strong&gt;product CSV only&lt;/strong&gt;. It deliberately refuses files that look like order or customer exports&lt;br&gt;
(it detects buyer-PII column names and stops) — your customers' data never goes through it.&lt;/p&gt;
&lt;h2&gt;
  
  
  How it compares
&lt;/h2&gt;

&lt;p&gt;The existing tools (Matrixify, Ablestar) are powerful full migration suites. Merchants who don't&lt;br&gt;
need all of that consistently say the same three things: &lt;strong&gt;expensive, slow, and hard to learn.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This tool is the opposite end: one command, one purpose — &lt;em&gt;catch the import-breaking mistakes before&lt;br&gt;
you upload&lt;/em&gt; — with no account and no upload of your catalog.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Full migration apps&lt;/th&gt;
&lt;th&gt;CSV Preflight Validator&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Setup&lt;/td&gt;
&lt;td&gt;Install app, connect store&lt;/td&gt;
&lt;td&gt;Run one command locally&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Touches your store&lt;/td&gt;
&lt;td&gt;Yes (Admin API)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;No — file in, file out&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Your catalog leaves your machine&lt;/td&gt;
&lt;td&gt;Often&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Never&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Job&lt;/td&gt;
&lt;td&gt;Migrate everything&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Stop a bad import&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;It's on GitHub — read the source, grab a release, run it on your own file:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/q00tar00/shopify-csv-preflight" rel="noopener noreferrer"&gt;https://github.com/q00tar00/shopify-csv-preflight&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv tool &lt;span class="nb"&gt;install &lt;/span&gt;csv-preflight
csv-preflight check your-products.csv &lt;span class="nt"&gt;--out-dir&lt;/span&gt; ./out
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a silent partial import has ever bitten you, I'd love to hear what broke — drop a comment or open&lt;br&gt;
an issue. I'm validating whether this is worth turning into a paid one-shot / Shopify app, and real&lt;br&gt;
merchant pain is exactly what I'm looking for.&lt;/p&gt;

</description>
      <category>shopify</category>
      <category>python</category>
      <category>cli</category>
      <category>csv</category>
    </item>
  </channel>
</rss>
