Debugging a mapping
Most mapping problems fall into three categories: a JSONata expression that crashes on a specific row, output that loads but produces the wrong shape in Shopify, and a transform that succeeds but a downstream load rejects. This page shows how to diagnose each.
The debugging loop
The fastest cycle is editor → sample → inspect:
- Open the mapping in the editor (Migration → Mappings → select resource → Edit).
- Paste the failing source row into the Sample input panel.
- Evaluate — the output panel shows what Graftport would actually send to Shopify.
- Fix the expression, re-evaluate, repeat.
- Once the output looks right, save a new version.
- Run transform-only scoped to that resource to re-stage the rows.
See Mappings → The mapping editor for the editor UI in detail.
Finding the failing row
A transform run that completes with errors leaves a run item for each failed row. From the run detail page:
- Click the resource type that shows errors.
- The run items list opens. Filter by status Error.
- Click a run item to see the JSONata error message and the source record that triggered it.
- Copy the source record — use this as the sample input in the editor.
Run items persist across runs. You can open a run item from a previous run to examine the input/output pair even after you’ve already fixed the mapping. Useful for regression checks.
Common JSONata errors
| Error text | Meaning | Fix |
|---|---|---|
instance member of undefined | The expression references a field path that doesn’t exist on this row (e.g. $.weight_unit when the product has no weight). | Guard with a conditional: $.weight_unit ? $.weight_unit : "kg". |
cannot evaluate function | A function name is misspelled or missing the $ prefix. | Check the function name against the JSONata reference. |
cannot cast type 'null' to number | A numeric operation received null (often from an optional field). | Use $number($.field ?? 0). |
stack overflow | A recursive expression or a very deep nested structure. | Flatten the expression; avoid deeply nested $map inside $map. |
Output loads but looks wrong in Shopify
If the transform succeeds but the Shopify record is wrong, the issue is in the mapping’s output shape, not in a runtime error.
Inspect a staged record
From the migration detail page, open Data → Staged records and find the record. The staged record shows the exact Shopify-shaped payload Graftport would send.
Compare to the expected Shopify shape
Open the Resource mappings page for the resource type. The table there lists every Shopify field and how the default mapping populates it.
Find the divergence
Look for the field that’s wrong in the staged record. Copy the staged record’s JSON and search for that field — the value shows you what the mapping is producing.
Fix the mapping expression
Go to the editor, use the staged record’s source row as the sample input, and correct the expression for the wrong field.
Save and re-transform
Save creates a new mapping version. Run transform-only scoped to this resource to re-stage all rows with the corrected version.
Load rejects a record
Load errors come from Shopify’s API. They appear on the run item’s load phase. Common cases:
| Error | Cause | Fix |
|---|---|---|
handle has already been taken | A product with the same Shopify handle exists on the destination. | Edit the mapping’s handle field to add a suffix (e.g. SKU-based). Re-transform, re-load. |
Access denied for write_products | The destination token is missing the required scope. | Reissue the token with the correct scope; update destination credentials. |
SHOPIFY_BUNDLES_NOT_ENABLED | A bundle record was pushed but the destination store doesn’t have the Shopify Bundles app installed. | Install the Shopify Bundles app on the destination store and re-run. |
Value is too long (maximum is 255 characters) | A mapped string field exceeds Shopify’s field length limit. | Add a truncation expression: $substring($.long_field, 0, 255). |
See Troubleshooting → Common errors for a fuller triage table.
Mapping version mismatch
If records are staging with a payload that doesn’t match what’s in the editor, you’re probably looking at a pinned version that differs from the current draft.
On the migration’s Mappings tab, each resource shows its pinned version number. The editor shows the version you’re editing. If the migration is pinned to version 3 and you’re editing version 5, a transform run will use version 3 until you re-pin.
To re-pin: from the Mappings tab, select the resource, click Pin version, and choose the version you just saved. Then re-run transform.
See Mappings → Templates & versions for how versioning and pinning work.