transloadit/uppy · error · TypeError
[s3mini] uploadId must be a non-empty string
Error message
[s3mini] uploadId must be a non-empty string
What it means
A parameter guard inside _validateUploadPartParams, invoked by uploadPart, requiring `uploadId` to be a non-empty string. The uploadId is the token S3 returns from createMultipartUpload and identifies the multipart session; without it the part cannot be associated with any upload. Throws a TypeError when uploadId is missing, not a string, or whitespace.
Source
Thrown at packages/@uppy/aws-s3/src/s3-client/S3mini.ts:167
const msg = `${C.ERROR_ENDPOINT_FORMAT} But provided: "${raw}"`
throw new TypeError(msg)
}
}
private _checkKey(key: string): void {
if (typeof key !== 'string' || key.trim().length === 0) {
throw new TypeError(C.ERROR_KEY_REQUIRED)
}
}
private _validateUploadPartParams(
key: string,
uploadId: string,
partNumber: number,
): void {
this._checkKey(key)
if (typeof uploadId !== 'string' || uploadId.trim().length === 0) {
throw new TypeError(C.ERROR_UPLOAD_ID_REQUIRED)
}
if (!Number.isInteger(partNumber) || partNumber <= 0) {
throw new TypeError(
`${C.ERROR_PREFIX}partNumber must be a positive integer`,
)
}
}
/**
* Uploads an object to S3 using XHR for progress tracking.
*/
public override async putObject({
key,
data,
fileType = C.DEFAULT_STREAM_CONTENT_TYPE,
onProgress,
signal,
}: IT.PutObjectParams) {View on GitHub (pinned to 5d4dedd02a)
Solutions
- Capture and reuse the uploadId returned from createMultipartUpload: `const { uploadId, key } = await s3.createMultipartUpload(...)` then pass it to every uploadPart call.
- If resuming, persist {key, uploadId} (e.g. localStorage) and verify it's still a non-empty string before calling uploadPart.
- If uploadId is missing, start a fresh multipart upload (or use listParts to revalidate) instead of calling uploadPart.
Example fix
// before
const { uploadId } = await s3.createMultipartUpload({ key })
await s3.uploadPart({ key, uploadId: id /* typo: undefined */, partNumber: 1, body })
// after
await s3.uploadPart({ key, uploadId, partNumber: 1, body }) Defensive patterns
Strategy: validation
Validate before calling
if (typeof uploadId !== 'string' || !uploadId.trim()) {
const created = await s3.createMultipartUpload({ key })
uploadId = created.uploadId // start fresh session
}
await s3.uploadPart({ key, uploadId, partNumber, body }) Type guard
const hasUploadId = (v: unknown): v is string => typeof v === 'string' && v.trim().length > 0
Prevention
- Persist {key, uploadId} immediately after createMultipartUpload if resuming later.
- Destructure createMultipartUpload's response once and thread it through all part uploads.
When it happens
Trigger: Calling `s3.uploadPart({ key, uploadId: undefined, partNumber, body })` — typically because the createMultipartUpload result was not stored/propagated, or a resume flow loaded state where uploadId was lost; passing null or '' explicitly.
Common situations: Resuming uploads after a page reload where persisted state lost the uploadId; a typo destructuring `{ id }` instead of `{ uploadId }` from the create response; concurrent upload state overwritten by another file's session; retry logic that forgets to thread uploadId through.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- [s3mini] key must be a non-empty string
- [s3mini] partNumber must be a positive integer
- [s3mini] fileType must be a string
- [s3mini] Failed to create multipart upload: ${JSON.stringify
- [s3mini] Missing ETag in uploadPart response headers
AI-assisted analysis of transloadit/uppy@5d4dedd02a (2026-08-28).
Data as JSON: /api/errors/844a2adc54ac5c6a.
Report an issue: GitHub.