uploadProductFirmware gives HTTP 500: Unexpected field

I’m trying to upload some firware to the Particle Cloud using uploadProductFirmware from the JS SDK, like

await particle.uploadProductFirmware({
            file: file,
            version: version,
            title: title,
            description: description,
            product: product,
            auth: token
        })

where file is a string, the path to the file, version the integer version number, and all the other params strings, as expected. product and auth are working on other API calls, so it can’t be them

However, I get this mysterious error, with HTTP 500:

{
    "ok": false,
    "error": "Unexpected field"
  }

Any ideas what’s going on here?

I was able to reproduce this and could not find a solution. I was able to implement it using node-fetch and form-data with only a few more lines of code:

const fs = require('fs');
const path = require('path');

const fetch = require('node-fetch');
var FormData = require('form-data');

const argv = require('yargs').argv;

const accessToken = process.env.PARTICLE_AUTH;
if (!accessToken) {
    console.log('You must specify the PARTICLE_AUTH environment variable');
    process.exit(1);
}

if (!argv.product) {
    console.log('You must specify --product <product_id> on the command line');
    process.exit(1);
}

if (!argv.vers) {
    console.log('You must specify --vers <version_num> on the command line');
    process.exit(1);
}

if (!argv.file) {
    console.log('You must specify --file <path> on the command line');
    process.exit(1);
}

if (!argv.title) {
    console.log('You must specify --title "<title_string>" on the command line');
    process.exit(1);
}

if (!argv.desc) {
    console.log('You must specify --desc "<desc_string>" on the command line');
    process.exit(1);
}


async function run() {
    const firmwareBin = fs.readFileSync(argv.file);

    var form = new FormData();
    form.append('version', argv.vers);
    form.append('title', argv.title);
    form.append('description', argv.desc);
    form.append('binary', firmwareBin, {filename: 'firmware.bin'});
    form.append('mandatory', 'false');

    const url = 'https://api.particle.io/v1/products/' + argv.product + '/firmware?access_token=' + accessToken;

    const result = await new Promise((resolve, reject) => {
        fetch(url, { method: 'POST', body: form })
        .then(function(res) {
            return res.json();
        }).then(function(json) {
            resolve(json);
        }).catch(function(e) {
            reject(e);
        });
    });

    console.log('result', result);
}

run();

I can also confirm this issue with pure HTML/JS (original inspiration stackoverflow)

<html>
  <head>
      <meta charset="utf-8"/>
</head>
<style>
  html {
    background-image: linear-gradient(163deg, #df80ff, #aaff80);
}

.btn-fs2 {
  position: absolute;
  top: 60px;
  left: 10px;
  padding: 5px;
  color: red;
  border: 1px solid blue;
  border-radius: 5px;
  z-index: 10;
  cursor: pointer;
}
					
</style>
<input id="myInput" type="file">
<body>
  
<div class="btn-fs2" id="btnFS2">
    Upload
</div>

<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/particle-api-js@8/dist/particle.min.js"></script>
<script type="text/javascript">

var accessToken = "XXXXXXXXXXXXXXXXXXX"; not display for security
var version = Number('102');
var product = "4292";
var title = "uptry";
var description = "somedesc";
var particle = new Particle();
var fs2 = document.getElementById('btnFS2');
fs2.addEventListener('click', uploadFile);



function uploadFile(){
  var files = document.querySelector('input').files[0];
  var reader = new FileReader();
  reader.onload = processFile(files);
  reader.readAsDataURL(files); 
}

function processFile(theFile){
  return function(e) { 
    var theBytes = e.target.result; 
    uploadFirmware(theBytes);
  }
}

function uploadFirmware(file){
     particle.uploadProductFirmware({ 
            file: new Blob([file], {type: "application/octet-stream"}),
            version: version,
            title: title,
            description: description,
            product: product,
            auth: accessToken
            }).then(
     function(data){
         console.log('Product Firmware uploaded successfully:', data);
       }, 
     function(err) {
         console.log('An error occurred:', err);
      });
}
</script>
</body>
</html>

and there is definitely something wrong with Particle JS SDK.
couldn’t find the work around for this but maybe someone @particle who is in charge of js SDK can have a look at this ?