transloadit/uppy · error · TypeError
[s3mini] fileType must be a string
Error message
[s3mini] fileType must be a string
What it means
createMultipartUpload validates its `fileType` option (the Content-Type stored with the object) and throws a TypeError if it is not a string. The parameter defaults to a standard stream content type, so this only fires when an explicit non-string value (null, undefined passed explicitly overriding the default, number, object) is supplied.
Source
Thrown at packages/@uppy/aws-s3/src/s3-client/S3mini.ts:212
})
return {
location: U.removeQueryString(url),
etag: U.sanitizeETag(xhr.getResponseHeader('etag')),
key,
}
}
/** Initiates a multipart upload and returns the upload ID. */
public override async createMultipartUpload({
key,
fileType = C.DEFAULT_STREAM_CONTENT_TYPE,
signal,
}: IT.CreateMultipartUploadParams) {
// todo support metadata here too?
this._checkKey(key)
if (typeof fileType !== 'string') {
throw new TypeError(`${C.ERROR_PREFIX}fileType must be a string`)
}
const { xhr } = await this.request({
request: { method: 'POST', key },
contentType: fileType,
signal,
})
const parsed = U.parseXml(xhr.responseText) as Record<string, unknown>
if (parsed && typeof parsed === 'object') {
// Check for both cases of InitiateMultipartUploadResult
const uploadResult =
(parsed.initiateMultipartUploadResult as Record<string, unknown>) ||
(parsed.InitiateMultipartUploadResult as Record<string, unknown>)
if (uploadResult && typeof uploadResult === 'object') {
// Check for both cases of uploadIdView on GitHub (pinned to 5d4dedd02a)
Solutions
- Pass a string: `fileType: file.type || 'application/octet-stream'`.
- If you don't know the type, omit the option entirely so the default content type applies.
- Verify you're passing `file.type` (string), not `file` (File object) or a MIME-map lookup result that may be null.
Example fix
// before
await s3.createMultipartUpload({ key, fileType: file }) // File object
// after
await s3.createMultipartUpload({ key, fileType: file.type || 'application/octet-stream' }) Defensive patterns
Strategy: type-guard
Validate before calling
const fileType = typeof file.type === 'string' && file.type ? file.type : 'application/octet-stream'
Type guard
const isFileType = (v: unknown): v is string => typeof v === 'string'
Prevention
- Default MIME types with `file.type || 'application/octet-stream'` everywhere.
- Pass file.type, never the File object, as fileType.
When it happens
Trigger: Calling createMultipartUpload({ key, fileType: file.type }) where file.type is undefined/'' is fine only when omitted; explicitly passing fileType: null, a number, or an object (e.g. the whole File instead of file.type) triggers it. Also passing fileType: undefined explicitly does NOT trigger it (default applies), so the real triggers are non-string truthy-or-null wrong types.
Common situations: Passing the File object itself instead of `file.type`; fileType sourced from a MIME lookup that returns false/null on unknown extensions; a config object where contentType field was renamed and is now undefined-overriding-default behavior after a version bump.
Understand the failure class
Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.
Related errors
- [s3mini] key must be a non-empty string
- [s3mini] uploadId must be a non-empty string
- [s3mini] partNumber must be a positive integer
- [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/e8ffdd287963ca44.
Report an issue: GitHub.