Understanding how to add and modify fields in Sanity documents

31 replies
Last updated: Feb 25, 2022
The query I got is not equal to the schema I created, it lacks "grade".
export default {
    name: 'user',
    title: 'User',
    type:'document',
    fields:[
        {
            name:"userName",
            title:"UserName",
            type:"string"
        },
        {
            name:'image',
            title: 'Image' ,
            type:'string'
        },
        {
            name:"admin",
            title:"Admin",
            type:"boolean",
            initialValue: false,
        },
        {
            name:"grade",
            title:"Grade",
            type:"string",
            initialValue: "somethingpls"
        }
    ],
}
AI Update

This is a common issue! When you add a new field to an existing schema in Sanity, existing documents won't automatically have that field populated, even if you've set an initialValue. The initialValue only applies when creating new documents, not to documents that already exist in your dataset.

Here's what's happening: Your existing user documents were created before the grade field existed in your schema, so they simply don't have that field in their stored data. When you query them, you're seeing the actual document data, which lacks the grade field.

Solutions

Option 1: Edit documents manually (for small datasets)

The simplest approach is to open each existing document in Sanity Studio and save it. This will apply the initialValue to that document. However, this isn't practical if you have many documents.

Option 2: Run a content migration (recommended for larger datasets)

Use Sanity's migration tooling to add the missing field to all existing documents:

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

export default defineMigration({
  title: 'Add grade field to existing users',
  documentTypes: ['user'],
  
  migrate: {
    document(doc, context) {
      return at('grade', setIfMissing('somethingpls'))
    }
  }
})

Create this migration with:

npx sanity@latest migration create

Then run it with:

npx sanity@latest migration run

Option 3: Use GROQ to provide defaults in queries

You can also handle this in your queries using GROQ's coalesce function to provide a default value when the field is missing:

*[_type == "user"] {
  userName,
  image,
  admin,
  "grade": coalesce(grade, "somethingpls")
}

This doesn't modify your documents but ensures your query results always include a grade value.

The migration approach (Option 2) is generally best because it actually updates your data to match your schema expectations, making your dataset consistent going forward.

Then here's the query I wrote:
When I console.log the query, it gives me this:
The result in the console doesn't include grade
why?
oh I see. Then would the grade attribute be created as well?
at least it should give grade: undefined
No, because the Content Lake is schemaless, so grade doesn't exist until you set it.
How do I affect the existing document in client?
Also, in the backend, it does have grade
The studio has grade but the printed out user doesn't have grade
Even after I gave a value to the grade manually, it still doesn't have it, so I am confused, is the process of fetching wrong, or the document is wrong
As I said, the backend it schemaless. That field only exists in the Studio UI until you set it.
If you specifically said in your query:

*[_type == 'user' //other criteria]{
  ...,
  grade
}
It
would give you a
null
for grade.
To retroactive apply information to existing documents, you have to run a
mutation either via the API or a client .
One thing to check if you have set the field and it's not coming through on your frontend is whether or not you've published the change.
Lemme try publishing it again
Oh you are right!
got the grade now
man
Thx, it's solved, now I just need to learn how to change it
Come back if you're having trouble with the mutation. It's tricky when you first encounter it!
Cool, thankx!
Hey, I have trouble reading the doc of mutation. I don't know where this example is supposed to belong to:
I want every user able to set their grade in frontend
I know how to write a query like this, but I don't know where that example should be put at. It looks more like a console command.
Ah, if you're writing to your dataset from the frontend you'll need to use one of the clients. What frontend framework are you using?
I am using react. If I can do client.create, then I can also do client.patch right?
I did the client.create here
If I want to change value instead of creating, I can just use client.patch right? I didn't know this function before
Exactly. You'll want to use
patch
. If you look at this example:
client
  .patch('bike-123') // Document ID to patch
  .set({inStock: false}) // Shallow merge
  .commit() // Perform the patch and return a promise
  .then((updatedBike) => {
    console.log('Hurray, the bike is updated! New document:')
    console.log(updatedBike)
  })
  .catch((err) => {
    console.error('Oh no, the update failed: ', err.message)
  })
First, you give it the document ID you want to patch, then you set and object that matches the fields in your schema you want to change, then you commit those changes.
lol dude, it worked! Thank you
as simple as this
one time success no debug lol

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?