422 Unprocessable Entity error when uploading File using JavaScript Fetch API to FastAPI backend

Question:

The codes are as shown below.

Backend

api.py

@app.post("/caption")
async def caption(image: UploadFile = File(...)) -> str:
    # produce the caption
    caption = apiCaption(image)

    # save the image and caption information
    status = await apiSaveData(image, caption)

    return caption if status else "Something went wrong"

Frontend

submit.js
export default function SubmitButton({ image }) {
  const handleSubmission = async () => {
    let formData = new FormData();
    console.log(image);
    formData.append("file", image);

    await fetch("http://localhost:8000/caption", {
      method: "POST",
      body: formData,
    })
      .then(response => response.json())
      .then(result => {
        console.log("Caption:", result);
      })
      .catch(error => {
        console.error("Error:", error);
      });
  };
  return (
    <div>
      <button disabled={!image} onClick={handleSubmission}>
        Submit
      </button>
    </div>
  );
}

The server keeps showing:

Failed to load resource: the server responded with a status of 422 (Unprocessable Entity) error

I really don’t know why and the error code is quite ambiguous so cannot get the point.

Asked By: Jaewon Choi

||

Answers:

Make sure that on client side you use the same key (parameter’s name) given on server side for UploadFile. In your case, that is image, as shown in this line of your code:

async def caption(image: UploadFile = File(...))
                  ^^^^^

Hence, on client side, when appending the file to the FormData instance, you should use that key instead:

formData.append("image", image);

Please have a look at this answer for more details and examples. Also, for future reference, the 422 status code is not quite ambiguous, as you stated. The 422 response body will contain an error message about which field(s) is missing or doesn’t match the expected format, which will help you to resolve the issue.

Answered By: Chris