How to attach uploaded image asset to document field using patch?
I see what's happening! The error Content has invalid type: sanity.imageAsset indicates you're trying to set the image field directly to the asset reference, but Sanity's image field expects a specific structure.
When you upload an image asset successfully, you need to structure the image field as an object that contains the asset reference, not just pass the asset reference directly. Here's the correct structure:
// After uploading your image asset
const uploadedAsset = await client.assets.upload('image', fileBuffer, {
filename: 'my-image.jpg'
})
// Correct way to patch the image field
await client
.patch(documentId)
.set({
myImageField: {
_type: 'image',
asset: {
_type: 'reference',
_ref: uploadedAsset._id
}
}
})
.commit()Key points:
- The image field should be an object with
_type: 'image' - Inside that object, you need an
assetproperty that contains the reference - The reference itself is an object with
_type: 'reference'and_refpointing to your uploaded asset's_id
Common mistake (what's likely causing your error):
// ❌ WRONG - This causes "invalid type: sanity.imageAsset"
.set({
myImageField: {
_ref: uploadedAsset._id,
_type: 'reference' // or 'sanity.imageAsset'
}
})The image type documentation explains that when an asset is uploaded, "an asset metadata document is created, and a reference to that document is added to the asset field within the image field." This nested structure is what Sanity expects.
If you're also setting crop/hotspot data or custom fields (like captions), you'd include those at the same level as asset:
.set({
myImageField: {
_type: 'image',
asset: {
_type: 'reference',
_ref: uploadedAsset._id
},
caption: 'My image caption', // custom field if defined in schema
hotspot: { /* hotspot data */ } // if needed
}
})Show original thread6 replies
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.