Why this: yet another 400 gpx upload error on /api/0.6/gpx/create? (using Dart/Flutter)

I’m using Dart/Flutter with the http package. The code that runs after the return from the OAuth validation is:

var uploadUrl =
          '$proto://$apiHost/api/$api/gpx/create';
var mp = MultipartFile.fromString('file', sampleGPX,  // see solution below!
          filename: 'filename1',
          contentType: MediaType('application', 'gpx+xml'));
var request = MultipartRequest('POST', Uri.parse(uploadUrl))
          ..files.add(mp)
          ..headers['Authorization'] = 'Bearer $bearerAuth'
          ..fields['file']= 'filename1'
          ..fields['description'] = 'GPX track upload'
          ..fields['visibility'] = 'public';
if (!prodMode) {
        debugPrint('Request: ${request.toString()}');
        debugPrint('Request headers: ${request.headers}');
        debugPrint('Request fields: ${request.fields}');
        debugPrint(
         'Request file: ${request.files[0].filename} ${request.files[0].contentType}');
}
var response = await client!.send(request);

When invoked, the printout is:

Request: POST https://master.apis.dev.openstreetmap.org/api/0.6/gpx/create
Request headers: {Authorization: Bearer ...redacted...}
Request fields: {file: filename1, description: GPX track upload, visibility: public}
Request file: filename1 application/gpx+xml; charset=utf-8

And the response.statusCode is 400.

I’d be most grateful if anyone can see what I’m doing wrong. Thanks.

P.S. Obviously a more detailed message in the status (“Bad request”) would help track down such errors :slight_smile:

Answering my own question, it turns out that the first argument to MultipartFile.fromString() has to be ‘file’. This is NOT documented. I had ‘part1’ in there, but have emended it to ‘file’ so when somebody blindly copies the example they won’t waste the same time as I did on this.