How to attach uploaded image asset to document field using patch?

6 replies
Last updated: Apr 16, 2020
I’m having some trouble adding an image to a document using the the
client
. I am successfully uploading the image asset, but Im not sure how to attach that to the field I want in the document. My current attempt is using the
.patch
functionality and seems like it should be working, but its encountering an error `Content has invalid type:
sanity.imageAsset
I’ll post code and full error in thread.
AI Update

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:

  1. The image field should be an object with _type: 'image'
  2. Inside that object, you need an asset property that contains the reference
  3. The reference itself is an object with _type: 'reference' and _ref pointing 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 thread
6 replies
client.assets
          .upload('image', logoFile)
          .then(document => {
            console.log('The file was uploaded!', document)
            // document._type = 'image'
            client.patch(docID)
              .set({logo: document})
              .commit()
              .then(addedLogo => {
                console.log('Image Added')
                console.log(addedLogo)
              })
              .catch(error => {
                console.error('Upload failed:', error.message)
              })
          })
          .catch(error => {
            console.error('Upload failed:', error.message)
          })

.set({
  logo: {
    _type: "image", // <= or whatever the type name is for "logo"
    asset: {
      _type: "reference",
      _ref: document._id
    }
  }
})
It should be something like this, I believe
🔥 Worked like a charm! Thanks!
Hi
user Y
. I thought I’d post here because its so closely related to my other question.
What is the structure for creating a reference with
client.create
? This is what I’ve got that isn’t working

const doc = {
    _type: 'siteSubmissions',
    businessName,
    referenceId: {
      _type: 'sites',
      _ref: _id,
    },
}

const doc = {
    _type: 'siteSubmissions',
    businessName,
    referenceId: {
      _type: 'reference',
      _ref: _id,
    },
}
provided
refrenceId
 is a field of the type
reference
🔥 Thanks again for the blazing fast response!

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?