Error: unable to resolve image URL from source (undefined)

12 replies
Last updated: Sep 11, 2022
Because you’re passing
undefined
to the image URL builder, and it does not like that.
AI Update

This error happens because you're passing undefined (or a null/missing value) to the @sanity/image-url builder, and it can't generate a URL from a non-existent image reference.

Common causes:

  1. The image field is optional and hasn't been set - Check if your document actually has an image uploaded for that field
  2. Incorrect field path - You might be accessing the wrong property (e.g., image instead of mainImage)
  3. Missing nested property - Trying to access image.asset when image itself is undefined

Quick fix with optional chaining:

import { urlFor } from './imageUrlBuilder'

// Add a conditional check
{post.mainImage && (
  <img src={urlFor(post.mainImage).width(800).url()} alt={post.title} />
)}

// Or provide a fallback
<img 
  src={post.mainImage ? urlFor(post.mainImage).width(800).url() : '/placeholder.png'} 
  alt={post.title} 
/>

Debug by checking your data:

console.log('Image data:', post.mainImage)
// Should show something like: { _type: 'image', asset: { _ref: 'image-abc123...', _type: 'reference' } }

If it shows undefined, the image either hasn't been uploaded in Sanity Studio or your GROQ query isn't fetching it correctly. Make sure your query includes the image field:

*[_type == "post"] {
  title,
  mainImage,  // Make sure this is included
  // ... other fields
}

The @sanity/image-url package expects a valid SanityImageSource object with an asset reference - it can't work with undefined values. Always validate that your image data exists before passing it to the URL builder.

Are you passing it an address or the image field itself? If memory serves people tend to send it dereferenced addresses instead of the original full asset object stored with the field. It uses that more complete data to arrive at all the different transformed URLs.
const builder = ImageUrlBuilder(client); const fileBuilder = buildFileUrl(client);

export const fileUrl = (source) =&gt; fileBuilder.file(source);
export const urlFor = (source) =&gt; builder.image(source);
import React from "react";import { useEffect } from "react";
import { useState } from "react";
import moment from "moment";
import { client, fileUrl, urlFor } from "./sanityClient";

function App() {
const [books, setBooks] = useState([]);
console.log(books);
useEffect(() =&gt; {
const query = '*[_type == "primaryBooks"]';
client.fetch(query).then((data) =&gt; {
setBooks(data);
});
}, []);

return (
&lt;div&gt;
&lt;h1&gt;Hello Apear&lt;/h1&gt;
{books.map((book) =&gt; (
&lt;a href={
/read/${fileUrl(book.pdf_url)}
}&gt;read&lt;/a&gt; ))}
&lt;/div&gt;
);
}

export default App;
or if someone can explain to me how to fetch file from sanity by maping through or any video related to it send me please
very tired
There is no file builder function. Have you defined
buildFileUrl
yourself or are you expecting it to be there (it won’t)?
so i was trying to do it the same way of image url function
so any solution for me or video explaination
my array []
1. 02. :
3.
author4. :
a. "Openstax"
5.
pdf_url a. :
6.
asset i. :
7.
_ref8. :
1. "file-e110eda3ffce1a778846f5ebf959ff72fb953ee5-pdf"
9.
_type10. :
1. "reference"
11. [[Prototype]]
12. :
1. Object
13.
_type14. :
i. "file"
15. [[Prototype]]
16. :
i. Object
17.
title18. :
a. "College Physics"
19.
_createdAt20. :
a. "2022-09-09T22
:26:00Z"21.
_id22. :
a. "42f69f46-37c7-456c-8126-c45c84548f26"
23.
_rev24. :
a. "IE8tlwnnGIwBkp6cNnXiN6"
25.
_type26. :
a. "primaryBooks"
27.
_updatedAt28. :
a. "2022-09-09T22
:37:58Z"29. [[Prototype]]
30. :
a. Object

Alright, let’s clarify a few things.
Because your document has a
file
type, you can attach a file such as a PDF file. The way it works is that the file itself is uploaded to Sanity, and your document contains a reference to that asset. You then need to resolve that reference to retrieve the actual URL to the PDF file.
(Therefore, your field (
pdf_url
) probably has a misleading name. It’s not a “PDF URL” that you get on that document. It’s a reference to an asset object which points to a PDF file. But that’s just naming so it doesn’t matter too much.)
To do get the actual URL, you need to update your query.

*[_type == "primaryBooks"] {
  ...,
  "pdfUrl": pdf_url.asset->url
}
Now, your response will yield an array of books, and every book object will have a
pdfUrl
property which is mapped to a URL to the Sanity asset CDN (provided the book has an attached PDF file).
From there, you can pass that URL to a
<a>
element so that it opens it in the current tab. You can add
target="_blank"
to your link so it opens it in a new tab for instance.
👆
user F
is absolutely on point 💃 and
target_blank
is always a good choice ... Just btw (because I think it's cool): If you want the pdfs to be downloaded by clicking the link you can also add a simple
?do
to the URL at the end 😊

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?