Github Api Creating File Error 400

I am writing a program that needs to upload a file to a GitHub repo making use of the API. Using this as a reference. It looks like I have done everything correctly, but I keep getting a 400 error Problems parsing JSON upon sending a request.

I have double-checked the repo and file input,
I made sure the content is being encoded to Base64 correctly,
and the token is working on other requests so that is correct

The sha is gotten from sending a get request to the same URL and then taking the sha value of the returned json (get repository content)

function uploadFile(repo, file, contents, sha, token) {
    var body = { message: "Update", contents: btoa(contents), sha }

    return fetch("https://api.github.com/repos/" + repo + "/contents" + file, { "method": "PUT", body, "headers": { "Content-Type": "application/json", "Authorization": "token " + token } })
        .then(res => res.json())
        .then(data => { return data })
}

uploadFile("My/Repo", "A/File.txt", "Test Contents", "sha", "ghp_..") //https://api.github.com/repos/My/Repo/contents/A/File.txt 400 {message: "Problems parsing JSON", documentation_url: "https://docs.github.com/rest/reference/repos#create-or-update-file-contents"}

I have tried just sending the raw string.
I also tried turning the json into a string and sending that but that returns {message: "Invalid request.↵↵"content" wasn't supplied.", documentation_url: "https://docs.github.com/rest/reference/repos#create-or-update-file-contents"}

Does anyone know what is wrong?

Read the error message. "content" wasn't supplied." because you named it contents rather than content.

Thanks for noticing that, but that is not it, Plus I only got that error when I didn’t pass contents in the body.

Naturally, because it’s required…

:man_facepalming:t3: The code I supplied does not generate this errror, only when I turn the json into a string and send it. Also as it said changing contents to content does nothing

Fixed it, had to stringify the json with the content field instead of contents

(exactly like I said :upside_down_face:)

Not what you communicated

I apologize, that was a bit snarky :pray:

In my first reply I said that you named the field contents instead of content and that’s why it said "content" wasn't supplied.. That’s what I mean by “as I said”.