Duplicates and conflicts
Most of what makes ImportKit safe to re-run lives here. Four of the five import types recognise data that already exists, and you decide per import what should happen to it.
What counts as “already exists”
Each type has its own identity. Two rows with the same identity are the same thing, and a row whose identity matches something in your store is a collision.
| Type | Identity |
|---|---|
| Metafield definitions | ownerType + namespace + key |
| Metafield values | owner_type + owner_reference + namespace + key |
| Metaobject definitions | type |
| Metaobject entries | handle, within the target definition |
| Blog articles | none: every row is a new article |
That last row is the exception that matters: blog articles have no identity, no conflict mode and no pre-import check. Re-running an article file creates the articles again.
The three modes
The selector sits on the check step, labelled “If a definition already exists” or similar depending on the type. It applies to the whole import.
Skip: leave it unchanged Default
The existing thing is left completely alone. The row reports as a skip, and isn't charged.
This is the default because its worst case is that nothing happens. Use it when:
- you're topping up, adding what's missing without touching what's there;
- you're re-running a file to finish a job that ran out of credits;
- you're not certain what's already in the store.
Update: patch it with this row's values
The existing thing is modified to match your row. Charged, because it's a write.
What “patch” means depends on the type, and the differences are deliberate. See per-type update behaviour. Use it when:
- you're correcting data you imported earlier;
- your CSV is the source of truth and you're syncing from it;
- you're re-exporting from another system and want the current values to win.
The previous values are gone. ImportKit doesn't keep them and can't put them back. Run the check first to see which rows will update, and look at the current values in the Shopify admin before you replace them. The check doesn't show them.
Fail: report it as an error
The collision is treated as a row-level error. Nothing is written and nothing is charged.
Useful when a collision means something has gone wrong upstream:
- you believe the file contains only new data, and want to be told if it doesn't;
- you're validating a migration into what should be an empty store;
- you're checking whether two source systems overlap.
Think of it as an assertion. In Fail mode a clean run means “everything in this file really was new”.
Choosing quickly
| What you're doing | Mode |
|---|---|
| First import into a fresh store | Skip. The setting won't matter, and Skip is safe if it does |
| Adding fields or entries to a store that already has some | Skip |
| Correcting values you imported before | Update |
| Re-syncing from an external source of truth | Update |
| Finishing a cancelled or failed import | Retry (it keeps the job's original mode) |
| Finishing an import that ran out of credits | Skip, running the same file again |
| Verifying a file contains nothing that already exists | Fail |
| Not sure yet | Skip, run the check, read the report, then decide |
Re-checking under a different mode is free, so you can compare all three before committing.
Per-type update behaviour
“Update” isn't one behaviour. Shopify makes some things immutable, and rewriting others from a CSV would be destructive, so each type patches what it safely can.
Metafield definitions
Name, description, pin, access settings and validations are overwritten with your row's values. The type is never changed.
A row whose type differs from the existing definition is a
conflict in every mode, including Update, and reports:
already exists as "single_line_text_field" but this row says "multi_line_text_field"
Shopify makes metafield types immutable, because existing values are stored in that shape. To change a type, create a new definition under a different key and migrate the values.
Metaobject definitions
New fields are added. Existing fields are never rewritten. A row whose field type differs from the existing field produces a warning rather than an overwrite.
Field types are immutable and entries already hold data in them, so silently rewriting a definition's structure from a spreadsheet would be the most destructive thing this app could do. It doesn't.
The useful consequence: adding a field to an existing definition works well.
Re-import the row with the new field in the fields cell, in Update mode, and
only the addition happens.
Metaobject entries
The fields you mapped are overwritten on the existing entry, matched by handle. Fields not present in your file are left as they are.
This makes entries the best-behaved type for an ongoing sync: keep handles stable, re-export, re-import in Update mode.
Metafield values
The value is replaced. The check tells you which rows will update, but not what the current values are, so look at those in the Shopify admin before a bulk overwrite.
A blank value isn't skipped for metafield values: it's sent to Shopify as-is. Leave out any rows you don't want to change.
Duplicates inside one file
Conflict modes are about collisions with your store. Collisions within the file are handled separately, for metafield definitions, metaobject definitions (by type) and metaobject entries (by handle): the first occurrence is processed normally, and every later one is flagged. Metafield values and blog articles don't get in-file duplicate detection.
Row 47 — duplicate of row 12
This is caught by the pre-import check, before anything runs. It's a common symptom of concatenating exports, or of a spreadsheet fill-down going one row too far. Because the check spots it, you can fix the file for free instead of discovering it as a mid-import collision.
In-file duplicate detection is part of the check, so it isn't available above 50,000 rows. Those rows still can't create two of the same thing: the first one writes, and the second collides with it and follows your conflict mode. You just won't be warned in advance.
Conflict mode and Retry
Retry resumes a job using the conflict mode it was started with, and only touches rows that were never attempted. Rows that already succeeded are not revisited, so retrying can't double-write or double-charge.
Seeing all three, in one minute
Import any definitions file. Then upload the same file again and switch through each mode. The check reruns automatically every time you change it:
| Mode | Report | Credit cost | Store changes |
|---|---|---|---|
| Skip | All rows skip | 0 | None |
| Update | All rows update | One per row | Values patched |
| Fail | All rows conflict | 0 | None |
All three checks are free, and none of them writes anything.