🔮 Sanity Create is here. Writing is reinvented. Try now, no developer setup

Troubleshooting issues with migrating text fields to block content in Sanity

45 replies
Last updated: May 23, 2023
user Y
for https://www.sanity.io/schemas/migrate-plain-text-field-to-portable-text-a05f0300 , if I wanted to use my custom
, would I just replace
"_type": "block",
"_type": "blockContent",
? Also just want to confirm this still works for v3?
May 10, 2023, 2:55 PM
Not tried it in v3 but I imagine importing a client from a different place is only difference. Think you're correct on substituting the _type to your desired custom blockContent schema. You could test it by modifying your query to grab one document only.
May 10, 2023, 6:15 PM
So I tried doing this and running
sanity exec convertToPortableText.js --with-user-token
but I get a 403...
May 11, 2023, 12:50 AM
So I was able to run it on a single one... I then updated the field to be
      type: 'array',
      name: 'description',
      title: 'Description',
      description: 'A short little description of the result',
      of: [{ type: 'block' }],
and it crashed my entire studio...
May 11, 2023, 1:08 AM
Yea... this script is a little dangerous... I think I will wait for
user Y
user T
user A
to help me out on this because I go destroying my entire application 😅
May 11, 2023, 1:13 AM
Do we maybe have to setup CLI config file? https://www.sanity.io/docs/cli and import
import { getCliClient } from 'sanity/cli';
const client = getCliClient()
May 11, 2023, 4:02 PM
I mean I got it to start changing stuff, it’s just that it didn’t change it correctly… I don’t know if I need to change the type on defineField to blockContent first and then run the script or what… but I was getting [object Object] as the content in the box and when I switched the field to blockContent I got that it was missing keys and that I could generate them so I did and then my studio crashed which is that screenshot.
May 11, 2023, 4:04 PM
Try adding _key values when you build the patches might be a bug in that key generation.
May 11, 2023, 5:27 PM
How does the Portable Text array data look like?
May 12, 2023, 7:06 PM
That’s the schema type 🙂 What about the actual data?
May 12, 2023, 7:07 PM
Is this what you're looking for? This is what one of the areas I have
content looks like when I inspect.
May 12, 2023, 7:12 PM
At least that is what I see when I look at one of the fields that is block and then the text data that I want to update to block just looks like
notes: my text here
May 12, 2023, 7:26 PM
I am guessing I just need to generate some random
values? Is there a preferred way of generating these keys?
May 12, 2023, 9:07 PM
Because this is what it currently looks like in the raw json
May 12, 2023, 9:08 PM
So it looks like this statement is not true anymore
// length(description) returns null if description isn't a (Portable Text) array
is of type
it returns a length if there's content in it
May 12, 2023, 9:19 PM
And running it on a single item gives me
  responseBody: '{\n' +
    '  "error": {\n' +
    '    "description": "attribute depth 21 exceeds limit of 20",\n' +
    '    "type": "validationError"\n' +
    '  }\n' +
  details: {
    description: 'attribute depth 21 exceeds limit of 20',
    type: 'validationError'

May 12, 2023, 9:23 PM
You can use our UUID library to generate those https://www.npmjs.com/package/@sanity/uuid
May 12, 2023, 9:33 PM
Not sure what is going on. The data looks correct to me
May 12, 2023, 9:33 PM
The error code means you have a structure of more then 20 levels. Seems like something isn’t quite right in your dataset/documents?
May 12, 2023, 9:36 PM
So this is the schema for the service where I am trying to grab a single one to test for. But it errors out for some reason?
May 12, 2023, 9:38 PM
Is this the proper flow
1. Run this script
2. Update the type from
3. Refresh the page and the text should be block now?
Or should this be ran on items that are type text but have no content?
May 12, 2023, 9:38 PM
I will say it definitely makes the edit multiple times 😬
May 12, 2023, 9:42 PM
Ah. It’s because you’re nesting arrays in doc.description
May 12, 2023, 9:44 PM
Compare the length to 0 not null
May 12, 2023, 9:45 PM
Ah. It’s because you’re nesting arrays in doc.description
Where are you seeing that? I just copied your guide 😅
May 12, 2023, 9:46 PM
What needs to be changed here?
May 12, 2023, 9:47 PM
I’m deducing it from the error message and that you might have tried to run the script multiple times :) I’d look into the data on that field in your dataset
May 12, 2023, 9:54 PM
Oh ok, are my steps I listed above correct? Run the script and then update the type?
May 12, 2023, 9:58 PM
So it's not that I am running in multiple times, I guess it just keeps running it because there's no check on the length... However, if I do
_type == 'service' && title == "F.O.R. Maricopa" && length(description) == 0
nothing is found because description has a length even if it's a text field.
May 12, 2023, 10:08 PM
But I am not sure the best way to get the items where text isn't empty but avoid grabbing block content 🤔
May 12, 2023, 10:35 PM
Is there a way to check if the description has
in it at all?
May 12, 2023, 10:43 PM
documents [
    _id: '6d28de62-fd23-4132-9762-f537565932dd',
    _rev: 'horv6K5FakAt9hZtSfJPLd',
    description: 'Copa Closet, a resource of basic needs for K-12 students that is sponsored by Maricopa Unified School District. The program is operated by Amber Liermann, a Maricopa High School counselor who operates the program with the help of volunteers which includes the AFROTC program on campus. They provide the basic needs to students, which includes food, clothes, hygiene products, and school supplies.'
❯ sanity exec convertToPortableText.js
documents [
    _id: '08070212-effc-4b42-bd05-75b7ceb45780',
    _rev: 'WxhGDPsVhW8jtbbiloZmJC',
    description: [ [Object], [Object], [Object], [Object], [Object] ]
The first result is from a description that is
type: 'text'
and the length of description is 396, and the second one is where description is
type: 'block'
and the length is 5. Looks like the check for length is no longer a viable option.
May 13, 2023, 2:36 AM
How reliable is doing something like
const fetchDocuments = () =>
    `*[_type == 'service' && title == "COPA Closet" && description[0]._type != "block"][0...100] {_id, _rev, description}`

May 13, 2023, 2:42 AM
So that works other than now I get this error
May 13, 2023, 2:44 AM
What's weird is the data looks correct 🤔
May 13, 2023, 2:47 AM
user Y
just a nudge on this, hoping to wrap it up this weekend 🤞 🤞
May 19, 2023, 9:33 PM
Has anyone else converted text to block content? I’m still stuck at the “Expected type String, got array” error 🥲
May 22, 2023, 10:38 PM
is your description now?
May 22, 2023, 10:43 PM
Whelp I feel dumb now... I don't know if updating my studio did the trick or what... But I don't get that error now...
May 22, 2023, 10:48 PM
No worries! Does that mean that it’s sorted out now?
May 22, 2023, 10:48 PM
Yea! Now I just need my client to not touch anything while I run the migration 😆 thanks User!
May 22, 2023, 10:50 PM
ifRevisionID: doc._rev,
prevents the script from writing over documents that has been touched after it fetched them – but yeah, might as well reduce potential sources for error if you can
May 22, 2023, 10:51 PM
Gotcha! I did notice
[@portabletext/react] Unknown block type "span", specify a component for it in the `components.types` prop
[@portabletext/react] Unknown block type "span", specify a component for it in the `components.types` prop
Never got that before when using
type: 'blockContent'
from the start... I use
    block: {
      normal: ({ children }) => {
        return <p className={paragraphClasses}>{children}</p>
in my Customer Block Content
May 22, 2023, 11:24 PM
Whelp I ended up breaking this by trying to update multiple fields at once…
May 23, 2023, 4:23 AM
So I ran this and now I get "nodes is not iterable"
May 23, 2023, 4:30 AM
So I needed to add a check for length on the item that I was changing because it would create a block even if the description was empty 😅
May 23, 2023, 3:42 PM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?