“Handle must be unique”: two products claiming one handle

Ignored line #-## because handle example already exists

This is the only error on this list that is not an error. Shopify prints it as a notice, ignores the offending line, and reports the import as finished — which is why it is the one most often discovered weeks later.

Check your file in the converterRuns in this browser. Nothing is uploaded, and the check happens before you download.

Why Shopify raises it

The handle is a product’s identity. It is the last segment of the product URL and the key the importer matches on, and Shopify’s product CSV reference describes URL handle as “the unique identifier for each product”, derived from the title when you leave it blank.

When two product rows carry the same handle, the second is not a second product — it is a contradiction. Shopify’s solutions to common product CSV import problems lists the message under “Ignored line #-## because handle example already exists”, with the instruction: “Make sure you have a unique handle for each product in your CSV.”

Note the word ignored. Unlike a validation failure, this does not stop the import. The rest of the file imports, the summary email arrives, and one product is quietly absent. The alternative is worse: if you ticked Overwrite products with matching handles, the second row does not get ignored — it overwrites the first, and any column left blank in the import is written as blank over data that was there.

How to find it in your CSV

Sort by the handle column and look for adjacent repeats — but only compare product rows. A handle is supposed to repeat on a product’s own variant and extra-image rows; those carry the handle and leave Title blank. What you are looking for is two rows that both have a Title and the same handle.

In a spreadsheet: filter to rows where Title is non-empty, then conditionally format duplicates in the handle column. Two sources produce almost all real cases — a title that slugifies identically (“Blue Shirt” and “blue shirt” both become blue-shirt), and a product plus its variant-in-a-different-pack-size sold as a separate line.

How the converter prevents it

Two mechanisms, and they work in opposite directions.

First, when the tool generates handles from your titles it de-duplicates as it goes: the second “blue shirt” becomes blue-shirt-2, the third blue-shirt-3, and the counter is kept across the whole file so the numbering is stable no matter how the rows are ordered. You cannot produce a collision this way.

Second, when you map a column to URL handle — or use the Pro Handle from option to seed handles from a SKU or internal id — the values are yours and may well contain duplicates. The handle_duplicate rule in src/lib/validate.ts catches that: it counts product rows per handle (using each row’s provenance, so variant and image rows are excluded) and reports every row of any handle claimed by more than one product, naming the output row numbers:

Handle “test-product” is used by 2 separate products (output rows 1, 2).

It is an error, not a warning, so those rows are excluded when you tick export valid rows only — and because the error report names the rows, you can fix the source instead.

What a correct fix looks like

Decide what the two rows actually are. If they are genuinely one product with two variants, give them one handle and distinct option values, so they become a product row plus a variant row. If they are two products, give them two handles: the cheapest way is to leave the handle column unmapped and let the title-based de-duplication run, which produces blue-shirt and blue-shirt-2 — then rename the second to something meaningful before you import, because a handle is a URL your customers will see.

If you are re-importing to update existing products, the opposite applies: the handle must match the live one exactly, and that is the case where seeding handles from a stable id rather than the title is worth it — an edited title then still updates the same product instead of creating a second.

Before you retry the import

  • Fix the file, not the symptom. Shopify reports the first failure it meets, so a second error usually appears once the first is cleared.
  • Import into a development store or a draft-status batch first, so a half-correct file cannot put wrong data in front of customers.
  • If you are overwriting existing products by handle, export your live products first: a blank cell in the import can erase a value that is currently there.

Column-by-column reference: the Shopify product CSV format. Nexum Gate is not affiliated with Shopify Inc.