How to send file with attachTemporaryFile REST API?
Asked by Bohdan Maik:

I have next code, but it throws "Bad request. Status code: 400". What is wrong with code below (size of file from link 0.1mb, its png image):  

```
const res = await fetch(mediaUrl);

const arrayBuffer = await res.arrayBuffer();
const buffer = Buffer.from(arrayBuffer);
const filename = mediaUrl.split('/').pop();
const contentType =
  res.headers.get('content-type') || 'application/octet-stream';

const formData = new FormData();

formData.append('file', buffer, {
  filename,
  contentType,
});

const response = await fetch(urlForAttach, {
  method: 'POST',
  headers: {
    Authorization: `${authHeader}`,
    'X-Atlassian-Token': 'no-check',
    Accept: 'application/json',
    ...formData.getHeaders(),
  },
  body: formData,
});
```


Answers:
author: Gregory Chavez
body: Hello, [@Bohdan Maik](/t5/user/viewprofilepage/user-id/5547729)

First off, kudos for diving into code and trying to upload that PNG image. Now, let's troubleshoot:

The Mysterious 400 Error:  
When you encounter a 400 Bad Request status code, it's like the server saying, "Hey, buddy, something's fishy with your request. Check it!"  
So, what's the server side-eyeing? Let's find out.  
Inspect the Code Scene:  
Your code snippet looks promising, but let's break it down:

const res = await fetch(mediaUrl);  
const arrayBuffer = await res.arrayBuffer(); [dollar tree compass](https://www.dollartree-compass.com)  
const buffer = Buffer.from(arrayBuffer);  
const filename = mediaUrl.split('/').pop();  
const contentType = res.headers.get('content-type') \|\| 'application/octet-stream';  
const formData = new FormData();  
formData.append('file', buffer, {  
filename,  
contentType,  
});  
const response = await fetch(urlForAttach, {  
method: 'POST',  
headers: {  
Authorization: \`${authHeader}\`,  
'X-Atlassian-Token': 'no-check',  
Accept: 'application/json',  
...formData.getHeaders(),  
},  
body: formData,  
});

Let's put on our detective hats:

Clues and Suspects:  
Media URL (mediaUrl): Is this URL pointing to the right place? Double-check that it's indeed the PNG image you want to upload.  
Buffer Creation: You're converting the array buffer to a Node.js Buffer. All good here.  
Filename and Content-Type: You're extracting the filename and content type from the response headers. Solid detective work!  
FormData: You've created a FormData object and appended the buffer. No red flags so far.  
Request to urlForAttach: This is where the plot thickens. Let's investigate:  
Headers: You're setting the Authorization header and X-Atlassian-Token. Good job!  
Accept Header: You're accepting JSON. Nice.  
Body: You're sending the FormData. Seems legit.  
Possible Culprits:  
Content-Length Missing: Sometimes servers demand a Content-Length header. Let's add it:

const contentLength = JSON.stringify(formData).length;  
const response = await fetch(urlForAttach, {  
method: 'POST',  
headers: {  
Authorization: \`${authHeader}\`,  
'X-Atlassian-Token': 'no-check',  
Accept: 'application/json',  
'Content-Length': contentLength,  
...formData.getHeaders(),  
},  
body: formData,  
});

URL Encoding: Ensure that urlForAttach is properly encoded. No spaces or funky characters, please!  
The Verdict:  
Give your code a fresh run with these tweaks. If the server still raises an eyebrow, we'll dig deeper.  
Remember, even servers have their grumpy days. Patience, my friend!  
Detective Out:  
If all else fails, consider sending a coded message via carrier pigeon. (Okay, maybe not.)  
But seriously, keep tinkering, and may your requests be ever valid!

I hope this info is helpful to you.

Best Regard,  
Gregory Chavez


Tags: attachment

cloud

jira-service-management

jira-service-management-cloud

rest-api