"Error uploading image with JavaScript client: Invalid image, could not read metadata"

1 replies
Last updated: Dec 26, 2022
β€’ OK It turns out that, I was sending the BLOB via URL to the function and that was the problem. Leaving the code here in case someone gets the same err.Hello, I am trying to upload an image with javascript client but getting the following error. Anybody gets the same error before? The blob is the File object where I get from react dropzone.


{
    "response": {
        "body": {
            "statusCode": 400,
            "error": "Bad Request",
            "message": "Invalid image, could not read metadata",
            "details": "Input buffer contains unsupported image format"
        },
        "url": "<https://xx.api.sanity.io/v2022-03-10/assets/images/production?filename=634ff16fea978807370a020d>",
        "method": "POST",
        "headers": {
            "content-length": "150",
            "content-type": "application/json; charset=utf-8",
            "etag": "W/\"96-wI2AUJgOZsmnCanyui4zXBV3NKg\""
        },
        "statusCode": 400,
        "statusMessage": ""
    },
    "statusCode": 400,
    "responseBody": "{\n  \"statusCode\": 400,\n  \"error\": \"Bad Request\",\n  \"message\": \"Invalid image, could not read metadata\",\n  \"details\": \"Input buffer contains unsupported image format\"\n}"
}

export async function uploadImageBlob(blob: File, fileName: string) {

    console.log(blob)

    client.assets.upload('image', blob, { contentType: 'image/jpeg', filename: fileName })
        .then(() => { console.log('upload success')})
        .catch((err) => { console.log(err)});

}
AI Update

This is a common issue when uploading images with the Sanity JavaScript client! The error "Invalid image, could not read metadata" typically occurs when you're passing a URL or incorrect data format to client.assets.upload() instead of the actual file data.

As you discovered, the problem was sending the BLOB via URL to the function. The Sanity client expects the actual File object or binary data, not a blob URL string created with URL.createObjectURL().

Here's the corrected approach:

export async function uploadImageBlob(blob: File, fileName: string) {
    try {
        // Pass the File object directly - NOT a URL
        const result = await client.assets.upload('image', blob, { 
            contentType: blob.type || 'image/jpeg', // Use the actual file type
            filename: fileName 
        });
        
        console.log('Upload success:', result);
        return result;
    } catch (err) {
        console.error('Upload error:', err);
        throw err;
    }
}

Common causes of this error:

  1. Passing a URL instead of the File object - If you create a blob URL with URL.createObjectURL(blob) and pass that string to the upload function, it will fail. Always pass the actual File object.

  2. File type mismatch - Use blob.type to get the actual MIME type rather than hardcoding 'image/jpeg'. This ensures the content type matches the actual file.

  3. Corrupted or invalid file - Ensure the file from React Dropzone is a valid image format that Sanity supports (JPEG, PNG, GIF, WebP, SVG, etc.).

Working example with React Dropzone:

import { useDropzone } from 'react-dropzone';
import { client } from './sanityClient';

function ImageUploader() {
    const onDrop = async (acceptedFiles: File[]) => {
        const file = acceptedFiles[0];
        
        try {
            // Pass the File object directly - NOT a URL
            const asset = await client.assets.upload('image', file, {
                contentType: file.type,
                filename: file.name
            });
            
            console.log('Uploaded asset:', asset);
        } catch (error) {
            console.error('Upload failed:', error);
        }
    };
    
    const { getRootProps, getInputProps } = useDropzone({ 
        onDrop,
        accept: {
            'image/*': ['.jpeg', '.jpg', '.png', '.gif', '.webp']
        }
    });
    
    return (
        <div {...getRootProps()}>
            <input {...getInputProps()} />
            <p>Drop an image here</p>
        </div>
    );
}

The key takeaway: never convert the File to a URL before passing it to client.assets.upload(). The method expects the raw file data, which the File object from React Dropzone provides directly. Thanks for sharing your solution - it'll definitely help others who encounter this same error!

Hello
user G
you can always also publish something on our exchange , if you feel like it πŸ™‚ This way people will be able to find your snippet through google

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?