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 an interrupted job;
- 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: for metafield values it shows the value currently in your store next to each row, so you can see exactly what you're about to replace.
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 interrupted import | Skip, then Retry |
| 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.
The conflict mode selector
The selector open with all three options and their help text, ideally with the check results behind it showing skips that would become updates.
assets/screenshots/conflict-mode-selector.png
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 — 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 shows the current value first, which is the safeguard for a bulk overwrite.
Remember that blank cells are skipped rather than written, so Update mode can't blank a value out. Deleting a metafield is admin work.
Duplicates inside one file
Conflict modes are about collisions with your store. Collisions within the file are handled separately, and always the same way: the first occurrence is processed normally, and every later one is flagged.
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 press Re-check once per mode:
| 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.