transloadit/uppy · critical · TypeError
signRequest must be a function
Error message
signRequest must be a function
What it means
S3mini validates that signRequest, when provided, is a function. Passing anything else (a string, object, or the result of calling the function instead of the function itself) throws this TypeError before any request is made.
Source
Thrown at packages/@uppy/aws-s3/src/s3-client/S3mini.ts:65
private signRequest!: IT.SignRequestFn
constructor({
region = 'auto',
requestSizeInBytes = C.DEFAULT_REQUEST_SIZE_IN_BYTES,
requestAbortTimeout,
...rest
}: IT.S3Config) {
super({ requestAbortTimeout })
if ('signRequest' in rest) {
const { signRequest } = rest
if (!signRequest) {
throw new TypeError(
'Either signRequest or getCredentials must be provided',
)
}
if (signRequest && typeof signRequest !== 'function') {
throw new TypeError('signRequest must be a function')
}
this.signRequest = signRequest
} else if ('getCredentials' in rest) {
const { getCredentials, endpoint } = rest
if (typeof endpoint !== 'string' || endpoint.trim().length === 0) {
throw new TypeError(C.ERROR_ENDPOINT_REQUIRED)
}
if (getCredentials && typeof getCredentials !== 'function') {
throw new TypeError('getCredentials must be a function')
}
this.endpoint = new URL(this._ensureValidUrl(endpoint))
this.getCredentials = getCredentials
this.signRequest = this._createCredentialBasedSigner()
} else {
throw new TypeError(
'Either signRequest or getCredentials must be provided',View on GitHub (pinned to 5d4dedd02a)
Solutions
- Pass an async function receiving ({method, key, uploadId, partNumber}) and returning {url}
- If you meant client-side signing, pass endpoint plus getCredentials instead of a URL string
- Double-check you're passing the function reference, not its return value
Example fix
// before
new S3mini({ signRequest: '/api/s3/sign' }) // throws
// after
new S3mini({
signRequest: async (req) =>
(await fetch('/api/s3/sign', { method: 'POST', body: JSON.stringify(req) })).json(),
}) Defensive patterns
Strategy: type-guard
Validate before calling
if ('signRequest' in cfg && typeof cfg.signRequest !== 'function') throw new TypeError('signRequest must be a function') Type guard
const isSignRequestFn = (f: unknown): f is IT.SignRequestFn => typeof f === 'function'
Prevention
- Pass the function reference, never its result or a URL string
- Use TypeScript's S3Config type to catch this at compile time
- Unit-test the config builder before constructing the client
When it happens
Trigger: new S3mini({ signRequest: '/api/s3/sign' }) (passing a URL string instead of a function), or signRequest: await getSigner() where the promise already resolved to a non-function, or signRequest: mySigner() invoking instead of referencing the callback.
Common situations: Confusing the presign endpoint URL with the callback; passing an object like {url: ...} from a config file; accidentally invoking the function during wiring; JSON configs that can't hold functions.
Related errors
- getCredentials must be a function
- Either signRequest or getCredentials must be provided
- [s3mini] endpoint must be a non-empty string
- Endpoint is required for credential-based signing
- [s3mini] endpoint must be a valid URL. Expected format: http
AI-assisted analysis of transloadit/uppy@5d4dedd02a (2026-08-28).
Data as JSON: /api/errors/932b13eb99c97870.
Report an issue: GitHub.