Sanity V3 Desk Tool Crash: Empty Media Properties in Preview Prepare

7 replies
Last updated: Feb 12, 2023
Hi there! I'm converting our current V2 Studio to Sanity V3. Everything is working great, except with one specific schema (our post schema) the desk tool is crashing and I have no idea why. The debugging message is not helpful; seems to be something with vite?• it works in our V2 studio, but not in V3
â—¦ Am currently setting up the V3 studio into it's own repo from our monorepo so I'm able to see both.
• Nothing has changed in terms of content, I've copied all of the schema files over and viewing all other content in the studio works great except this one.
• Specific error screenshot in thread.
Edit:
âś… Solved! Solution: Make sure your
media
properties in preview
prepare
functions aren't empty. Used to fly in V2, no longer in V3.
AI Update

Great to hear you solved it! This is actually a common gotcha when migrating from Studio v2 to v3. The media property handling in preview configuration became stricter in v3.

In Studio v2, the preview system was more forgiving about empty or undefined media properties, but v3 requires them to be either a valid value or explicitly handled. When you have a prepare function that returns an empty media property, it can cause the desk/structure tool to crash.

The solution, as you discovered, is to ensure your media properties always have a value. Here are a few patterns that work well:

Provide a fallback icon:

import { DocumentIcon } from "@sanity/icons";

preview: {
  select: {
    title: 'title',
    media: 'image'
  },
  prepare({title, media}) {
    return {
      title,
      media: media ?? DocumentIcon  // Fallback to an icon
    }
  }
}

Or conditionally omit the media property:

prepare({title, media}) {
  return {
    title,
    ...(media && { media })  // Only include media if it exists
  }
}

This stricter validation is part of v3's move to a more predictable and type-safe architecture. While v2's webpack-based build system would sometimes silently handle these issues, v3's Vite-based build system (which is why you saw Vite in the error) is more strict about component props.

Thanks for sharing the solution – it'll definitely help others hitting the same issue during migration!

Show original thread
7 replies
What does the schema for this look like?
Hi RD!
export default {
  name: 'post',
  title: 'Post',
  type: 'document',
  groups: [
    {
      name: 'main',
      title: 'Main',
      default: true,
    },
    {
      name: 'seo',
      title: 'SEO',
    },
  ],
  fields: [
    {
      name: 'meta',
      title: 'Meta infomation',
      type: 'metaObject',
      group: 'seo',
    },
    {
      name: 'title',
      title: 'Title',
      type: 'string',
      validation: (Rule) => Rule.required(),
      group: 'main',
    },
    {
      name: 'slug',
      title: 'Slug',
      type: 'slug',
      options: {
        source: 'title',
        maxLength: 96,
      },
      description:
        'Click generate to auto-generate a slug based on the title. Slug is used for the URL of the page. Once a slug is created it should not be modified. In the event a slug must be modified, a task will need to be created for the fronted team to put in a redirect.',
      validation: (Rule) => Rule.required(),
      group: 'main',
    },
    {
      name: 'publishedAt',
      title: 'Published at',
      type: 'datetime',
      validation: (Rule) => Rule.required(),
      group: 'main',
    },
    // {
    //   name: 'author',
    //   title: 'Author',
    //   type: 'reference',
    //   to: { type: 'author' },
    // },
    {
      name: 'useYtThumbnail',
      title: 'Use YouTube Thumbnail as Post Thumbnail',
      type: 'boolean',
      description:
        'If toggled on, the thumbnail from the Youtube video will be used as the main image for the post.',
      group: 'main',
      initialValue: false,
    },
    {
      name: 'mainImage',
      title: 'Post Thumbnail',
      description:
        'This image will be used as the thumbnail for the post on the blog index.',
      type: 'image',
      group: 'main',
      hidden: ({ document }) => document.useYtThumbnail,
    },
    {
      name: 'categories',
      title: 'Categories',
      type: 'array',
      of: [{ type: 'reference', to: { type: 'category' } }],
      group: 'main',
    },
    {
      name: 'excerpt',
      title: 'Excerpt',
      type: 'text',
      description:
        'The text that will be displayed on the blog listings page. If no description is set, the first 120 characters of the body will be used.',
      group: 'main',
      rows: 3,
    },
    {
      name: 'body',
      title: 'Body',
      type: 'blockContent',
      group: 'main',
    },
  ],

  preview: {
    select: {
      title: 'title',
      author: 'author.name',
    },
    prepare({ title, subtitle }) {
      return {
        title: title,
        subtitle: subtitle,
        media: '',
      }
    },
  },
}
Ope I think I just solved it -
user M
deleting the empty "media" tag did the trick! I JUST noticed that, hahaha thank you.
Oh great! Was just about to spin up a version of this 🙂 Glad you got it sorted!
Thank you!!
You’re welcome!
I got exactly the same
user E
, you are sure that you have renamed the doc schemas from .js to .jsx? (which I hadn’t) because it works fine with
media: ''

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?