Error migrating data with CLI due to non-existent document reference

33 replies
Last updated: Jan 19, 2023
I have a singleton document set up following the guide here: https://www.sanity.io/guides/singleton-document
When I attempt to migrate data from staging to production using the CLI with
--replace
, I get the following error:
  sanity:client [589] Response body: {
  "error": {
    "description": "Mutation(s) failed with 1 error(s)",
    "items": [
      {
        "error": {
          "description": "Document \"landingPage\" references non-existent document \"6e064ed9-c668-4084-a803-8166a5a970f1\"",
          "id": "landingPage",
          "referenceID": "6e064ed9-c668-4084-a803-8166a5a970f1",
          "type": "documentReferenceDoesNotExistError"
        },
        "index": 0
      }
    ],
    "type": "mutationError"
  }
The only reference to this document is in the desk structure per that guide. Is there a way to get around this? I’m also confused because
landingPage
is not any of our types
AI Update

You're hitting a documentReferenceDoesNotExistError because your landingPage singleton document contains a reference field pointing to a document (ID 6e064ed9-c668-4084-a803-8166a5a970f1) that doesn't exist in your production dataset. When using --replace, Sanity validates all document references during import to maintain referential integrity, and the operation fails if any referenced documents are missing.

You're correct that this has nothing to do with your desk structure configuration from the singleton guide. The .documentId("landingPage") in your structure file is just for UI navigation—it doesn't create actual document references.

The "landingPage" in the error is the _id of your singleton document (which matches its schema type name, as configured in the guide). The document itself contains a reference field pointing to a non-existent document.

Solutions

1. Import All Documents (Recommended)

The most straightforward approach is to import your entire staging dataset, which includes both the singleton and all documents it references:

# Export from staging
sanity dataset export staging staging-export.tar.gz

# Import to production with --replace
sanity dataset import staging-export.tar.gz production --replace

This ensures all referenced documents exist before the singleton is validated.

2. Import Without --replace (Merge Mode)

If you don't need to completely replace the production dataset, import without the --replace flag. This merges the staging content into production without strict validation:

sanity dataset import staging-export.tar.gz production

Note: This only works if there are no document ID conflicts, or if you're okay with the imported documents overwriting existing ones.

3. Remove the Problematic Reference

If the reference isn't needed or is outdated, clean it up in staging first:

  • Open your staging Studio
  • Navigate to the landingPage document
  • Find the reference field pointing to the missing document
  • Remove or update the reference
  • Export and import again

4. Investigate the Reference

To identify which field contains the problematic reference:

# Export your staging dataset
sanity dataset export staging staging.tar.gz

# Extract and search for the reference
tar -xzf staging.tar.gz
grep "6e064ed9-c668-4084-a803-8166a5a970f1" data.ndjson

This shows you the exact document structure and which field contains the reference. You can then decide whether to include the referenced document in your export or remove the reference.

5. Use a Fresh Dataset

If you need a complete replacement and don't mind losing production data:

# Delete and recreate the production dataset (WARNING: destroys all data)
sanity dataset delete production
sanity dataset create production

# Import without --replace since the dataset is empty
sanity dataset import staging-export.tar.gz production

Why This Happens

The --replace flag enforces strict referential integrity validation. The most common cause is exporting only specific documents (like just your singleton) without including the documents they reference. The solution is typically to export the complete dataset or clean up the references before exporting.

It looks like the document with
_id: landingPage
is referencing a document that doesn’t exist in the new dataset. What does that landing page document look like?
import { DocumentDefinition } from "sanity"

export const etaLanding2021: DocumentDefinition = {
  name: "etaLanding2021",
  type: "document",
  title: "ETA 2021 Landing",
  preview: {
    prepare: () => ({
      title: "ETA 2021 Landing Page",
    }),
  },
  groups: [
    {
      name: "pageData",
      title: "Page Data",
      default: true,
    },
    {
      name: "seo",
      title: "SEO",
    },
  ],
  fields: [
    { type: "seo", group: "seo", name: "seo" },
    {
      title: "hero banner logo",
      name: "heroImage",
      type: "reference",
      to: [{ type: "reusableImage" }],
      group: "pageData",
    },
    {
      type: "string",
      title: "Youtube video (ID)",
      name: "youtubeVideoId",
      group: "pageData",
    },
    {
      type: "image",
      title: "Youtube video Poster image",
      name: "youtubeVideoPoster",
      group: "pageData",
    },
  ],
}
oooooooo
the reusable image
🤦‍♂️
Nailed it!
hm interesting, moving that over also failed with a mutation error
but that reusable image has no references
Did you also bring the asset?
it seems to re-trigger that same landing page error
when i try to import only the re-usable image types
this does include assets, yes
in all of the imports in question
 [  0%] Strengthening references (4.70s)  sanity:client [588] Response code: 409 Conflict +267ms
  sanity:client [588] Response body: {
  "error": {
    "description": "Mutation(s) failed with 1 error(s)",
    "items": [
      {
        "error": {
          "description": "Document \"landingPage\" references non-existent document \"6e064ed9-c668-4084-a803-8166a5a970f1\"",
          "id": "landingPage",
          "referenceID": "6e064ed9-c668-4084-a803-8166a5a970f1",
          "type": "documentReferenceDoesNotExistError"
        },
        "index": 0
      }
    ],
    "type": "mutationError"
  }
} +0ms
Can you try adding the
--allow-failing-assets
flag to see if the assets may be the issue?
Same error
I also tried re-publishing the doc with that field blank to hopefully “remove” the reference but the vision tool confirms it is still there
oh hmm. it seems like the singleton setup isn’t actually showing me the broken document.. it allowed me to create a new one
ok, well this is going to take some cleanup
ok, all set
Nice!
ok.. so not quite all set here. No matter what, this error seems to pop up
I have deleted the singleton “landingPage” document from production and am just trying to migrate over the reusable images first.. but I always get that same error when moving over the reusable images
even there are no landing page docs at all
it seems to get pulled in to the import with the reusable images for some reason?
and the reusable images don’t actually import
for some reason, when the assets get imported that document is created no matter what.. I think maybe because there is an asset (image) field in the document?
I confirmed the NDJson does not have the data for that document in it.. so somehow the data gets there via the assets json
in the studio I get a warning about strong vs weak references:
if I explicitly set weak to true in the schema it goes away. I did not have this specified before
ok well, I have no idea how I pulled it off but I got all the data over there. I think the key was throwing in a
--raw
export at some point along the way - this got the reusable image documents there but none of the assets associated (the image field in all docs was blank)
I also then had to change that field above to be strong, again, in the production dataset
I think that weak reference may have been happening because the import was failing while strengthening references.

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?