
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeBased on your error, it looks like you're trying to access mainImage on a post object that is null during the build process. This is a common issue with Next.js static site generation when some of your posts don't have a mainImage field populated, or when a post document doesn't exist at all.
Here are the most common causes and solutions:
If the post itself doesn't exist (maybe you're generating paths for posts that were deleted), you need to check if the post exists before accessing its properties:
// In your page.tsx
const post = await getPost(slug);
if (!post) {
notFound(); // Next.js 13+ App Router
// or return null / redirect
}
// Now safely access post.mainImage
const imageUrl = post.mainImage ? urlFor(post.mainImage) : null;Use the coalesce() function in your GROQ query to provide fallback values:
*[_type == "post" && slug.current == $slug][0] {
_id,
title,
slug,
"mainImage": coalesce(mainImage, null),
// or provide a default image object
body,
author->
}On line 53 of your page.tsx, use optional chaining to safely access mainImage:
// Instead of:
const imageUrl = urlFor(post.mainImage).url();
// Use:
const imageUrl = post.mainImage ? urlFor(post.mainImage).url() : '/default-image.jpg';
// Or with optional chaining:
const imageUrl = post?.mainImage ? urlFor(post.mainImage).url() : null;In your post.ts schema, ensure mainImage is marked as optional (which it likely already is):
{
name: 'mainImage',
title: 'Main Image',
type: 'image',
// No 'validation: Rule => Rule.required()' means it's optional
options: {
hotspot: true,
},
}If you're using generateStaticParams, you can filter out posts that don't have the required fields:
export async function generateStaticParams() {
const posts = await client.fetch(`
*[_type == "post" && defined(mainImage)] {
"slug": slug.current
}
`);
return posts.map((post) => ({
slug: post.slug,
}));
}The defined() function checks if the field exists and isn't null.
Based on typical Next.js + Sanity setups, you probably need to add a null check before accessing mainImage on line 53. The build process is trying to generate static pages for all posts, and at least one post either doesn't exist or doesn't have a mainImage field populated.
Try wrapping your image rendering logic like this:
{post.mainImage && (
<Image
src={urlFor(post.mainImage).url()}
alt={post.title}
// ... other props
/>
)}This will prevent the error by only rendering the image when mainImage actually exists. You can learn more about null handling in GROQ queries to handle these situations at the query level rather than in your component code.
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.
Content operations
Content backend


The only platform powering content operations
By Industry


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store