transloadit/uppy · critical · TypeError
getCredentials must be a function
Error message
getCredentials must be a function
What it means
When the getCredentials strategy is used, S3mini validates that getCredentials — if provided — is a function returning {credentials: {accessKeyId, secretAccessKey, sessionToken}, region}. Passing a non-function (string, object, or invoked result) throws this TypeError immediately in the constructor.
Source
Thrown at packages/@uppy/aws-s3/src/s3-client/S3mini.ts:75
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',
)
}
this.region = region
this.requestSizeInBytes = requestSizeInBytes
}
/** Creates a presigner that fetches/caches credentials and generates pre-signed URLs. */
private _createCredentialBasedSigner(): IT.SignRequestFn {
return async (View on GitHub (pinned to 5d4dedd02a)
Solutions
- Pass an async function that fetches and returns {credentials, region}, e.g. hitting your backend's credential endpoint
- If you truly have static creds, wrap them: getCredentials: async () => ({ credentials: {...}, region })
- Verify the return shape includes accessKeyId/secretAccessKey (and sessionToken for temporary creds)
Example fix
// before
new S3mini({ endpoint, getCredentials: myCredsObject }) // throws
// after
new S3mini({
endpoint,
getCredentials: async () => (await fetch('/api/s3/credentials')).json(),
}) Defensive patterns
Strategy: type-guard
Validate before calling
if ('getCredentials' in cfg && cfg.getCredentials != null && typeof cfg.getCredentials !== 'function') throw new TypeError('getCredentials must be a function') Type guard
const isGetCredentialsFn = (f: unknown): f is IT.GetCredentialsFn => typeof f === 'function'
Prevention
- Pass a callback, not a credentials object, so temporary creds can refresh
- Validate the callback's return shape in dev (accessKeyId, secretAccessKey)
- Rely on S3Config typing to catch non-function values
When it happens
Trigger: new S3mini({ endpoint, getCredentials: '/api/s3/credentials' }) (URL instead of function), or getCredentials: credsObject where the fetched credentials were passed directly rather than a callback that fetches them.
Common situations: Passing a static credentials object instead of a refreshable callback (breaks STS session renewal); confusing the endpoint URL with the credential-fetcher; invoking the function during wiring.
Related errors
- signRequest must be a function
- Endpoint is required for credential-based signing
- Either signRequest or getCredentials must be provided
- [s3mini] endpoint must be a non-empty string
- [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/40cb2a031d4ee38e.
Report an issue: GitHub.