FastAPI returns “Error 422: Unprocessable entity” when I send multipart form data with JavaScript Fetch API

The 422 error response body will contain an error message about which field(s) is missing or doesn’t match the expected format. Since you haven’t provided that (please do so), my guess is that the error is triggered due to how you defined the images parameter in your endpoint. Since images is expected to be a List of File(s), you should instead define it using the File type instead of Form. For example:

images: List[UploadFile] = File(...)
                           ^^^^    

When using UploadFile, you don’t have to use File() in the default value of the parameter, meaning that the below should work as well:

images: List[UploadFile]

Hence, the FastAPI endpoint should look similar to this:

@app.post("/user/register")
async def register_user(name: str = Form(...), images: List[UploadFile] = File(...)):
    pass

In the frontend, make sure to use the body (not data) parameter in the fetch() function to pass the FormData object (see example in MDN Web Docs). For instance:

var nameInput = document.getElementById('nameInput'); 
var imagesInput = document.getElementById('imagesInput');

var formData = new FormData();
formData.append('name', nameInput.value);
for (const file of imagesInput.files)
    formData.append('images', file);

fetch('/user/register', {
      method: 'POST',
      body: formData,
   })
   .then(response => {
      console.log(response);
   })
   .catch(error => {
      console.error(error);
   });

Please have a look at this answer, as well as this answer, which provide working examples on how to upload multiple files and form data to a FastAPI backend, using Fetch API in the frontend.

As for manually specifying the Content-Type when sending multipart/form-data, you don’t have to (and shouldn’t) do that, but rather let the browser set the Content-Type—please take a look at this answer for more details.

Leave a Comment