How to populate a field for existing entries via command line in Sanity?

20 replies
Last updated: Jan 6, 2022
Hey folks! I have a new field in Sanity Studio and I forgot to add an initial value for it...Is there a way for me to populate that field through the command lines for my hundreds of entries?
AI Update

Absolutely! You can backfill that field using a migration script run through the CLI. This is a common task and Sanity provides great tooling for it.

The modern, recommended approach is to use the sanity migration command, which has built-in batching, dry-run capabilities, and validation. Here's how to do it:

First, create a new migration:

npx sanity@latest migration create backfill-my-field

This creates a migration file where you can write your logic. Here's an example that backfills a field with a default value:

import { defineMigration, at, setIfMissing } from 'sanity/migration'

export default defineMigration({
  title: 'Backfill my new field',
  
  async *migrate(documents) {
    // Filter to only documents of your type that are missing the field
    yield* documents.byType('yourDocumentType')
      .filter('!defined(yourNewField)')
      .map((doc) => 
        at('yourNewField', setIfMissing('your default value'))
      )
  }
})

Then run it with:

npx sanity@latest migration run backfill-my-field

By default, this runs in dry-run mode so you can preview changes. When ready, add --no-dry-run to actually apply the changes.

Using sanity exec (Alternative)

You can also use sanity exec --with-user-token for more custom logic. Create a script file (e.g., backfill.js):

import {getCliClient} from 'sanity/cli'

const client = getCliClient()

// Fetch all documents missing the field
const query = '*[_type == "yourDocumentType" && !defined(yourNewField)]'
const documents = await client.fetch(query)

console.log(`Found ${documents.length} documents to update`)

// Batch update them
const transaction = client.transaction()

documents.forEach(doc => {
  transaction.patch(doc._id, {
    set: { yourNewField: 'your default value' }
  })
})

await transaction.commit()
console.log('Done!')

Run it with:

sanity exec backfill.js --with-user-token

The --with-user-token flag gives your script authentication with your user permissions.

Important Tips

  1. Always backup first: Export your dataset before running any bulk operations:

    sanity dataset export
  2. Make it idempotent: Use filters like !defined(yourNewField) so you can safely re-run the script without creating duplicates or overwriting data.

  3. Use transactions: Batch your mutations into transactions (as shown above) to avoid rate limits and improve performance.

  4. Test with a limit: During development, add .slice(0, 10) to your documents array to test on just a few documents first.

The sanity migration approach is generally preferred because it handles batching automatically, provides better visual feedback, and validates against your schema. But sanity exec gives you more flexibility for complex custom logic.

Show original thread
20 replies
There is! You can use the Mutations API .
Great!
Great!
The weird thing is that I deployed with these initial values
initialValue: {
    saved: false,
    ash:3
  }
My field is in studio but the initial value is not...
In this situation, you wouldn't use
initialValue
. You would directly set the field. So, it would be something like:
{
  "saved": "false",
  "ash": "3"
}
You mean if I want to use Mutation?
But I would like to understand what I missed when deploying my schema.
Correct. Am I misinterpreting that second question 😅 ?
export default {
  name: "logs",
  title: "Burn logs",
  type: "document",
  fields: [
    {
      title: "Date",
      name: "date",
      type: "datetime",
      options: {
        dateFormat: 'YYYY-MM-DD',
        timeFormat: 'HH:mm'
      },
    },
    {
      title: "Collections",
      name: "collections",
      type: "reference",
      to: { type: 'collections' },
    },
    {
      title: "Token",
      description: "The token ID",
      name: "token",
      type: "string"
    },
    {
      title: "TX",
      description: "Transaction ID",
      name: "transactionID",
      type: "string"
    },
    {
      title: "ID",
      name: "id",
      type: "string"
    },
    {
      title: "Thumbnail",
      name: "thumbnail",
      type: "image"
    },
    {
      title: "Owner",
      name: "owner",
      type: "string"
    },
    {
      title: "Voxel ID",
      description: "This is the MINT ID of the voxel installation used to burn the NFT.",
      name: "voxelID",
      type: "string"
    },
    {
      title: "Number of ASH dropped",
      description: "Amount of $ASH dropped during the burning process...",
      name: "ash",
      type: "number",
      validation: Rule => Rule.required().integer().positive()
    },
    {
      title: "Booster ID",
      description: "This is the MINT ID of the booster NFT.",
      name: "boosterID",
      type: "string"
    },
    {
      title: "Last Words",
      name: "lastWords",
      type: "string",
      initialValue: "Rest in peace"
    },
    {
      title: 'Burn log published on discord?',
      name: 'published',
      type: 'boolean'
    },
    {
      title: 'Last words saved?',
      name: 'saved',
      type: 'boolean'
    }
  ],
  initialValue: {
    saved: false,
    ash:3
  }
}
Sorry, I have been coding for the last 15 hours my brain is fried.
Could you please confirm that I used 'initialValue' properly in this case?
OK, cool. Thanks for that. Yes, that looks correct. That initial value would show up in a newly created document.
Ok.
Make sense. I deployed before the inital value.
So now I need to patch everything.
Thank you Rachael.
Appreciate the patience 🙂
For sure! Let me know if it's not working as intended!
Of course. Thanks.

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?