@tus/s3-store: gracefully handle zero byte uploads (#824)
This PR resolves an issue with zero byte uploads on S3 or Minio.
## Error message
- S3: `MalformedXML: The XML you provided was not well-formed or did not
validate against our published schema`
- Minio: `InvalidRequest: You must specify at least one part`
## Reproduction
Any upload with zero bytes will reproduce this issue. This is a simple
repro using `tus-js-client`
```JavaScript
import * as tus from 'tus-js-client'
const upload = new tus.Upload(Readable.from(Buffer.alloc(0)), {
endpoint,
chunkSize: 1024,
uploadSize: 0,
retryDelays: [],
uploadDataDuringCreation: true,
metadata: {
bucketName: 'my-bucket',
objectName: 'some/object/path.ext',
},
onError: (error) => {
console.error("onError", error)
},
onSuccess: () => {
console.log(`onSuccess`)
},
})
upload.start()
```
## Additional context
Including the `StreamLimiter` transform as is done [here in
BaseHandler](https://github.com/tus/tus-node-server/blob/8906f1454f171a4b964bcf7a4d6fa41a0636f2b9/packages/server/src/handlers/BaseHandler.ts#L189)
causes zero byte chunks to not be emitted. This means that
`chunkFinished` is never called and therefore no part is ever created.
This results in the error as described above because you cannot complete
a multipart upload that has no parts.
The test suite already has a test for zero byte uploads, but it doesn't
use `StreamLimiter` so it succeeds. I've added a mostly identical test
that includes `StreamLimiter` which consistently reproduces the issue.
As a fix I simply check if there are zero parts and add an empty part
before trying to finalize the upload.
This PR also adds the AWS_ENDPOINT env to tests to allow testing locally
against Minio L
Lenny committed
0f3ec0c7318820589dd41b6830aba2954828ac78
Parent: 8906f14
Committed by GitHub <noreply@github.com>
on 4/21/2026, 7:28:46 PM