transloadit/uppy · warning · TypeError

getCredentials must be a function

Error message

getCredentials must be a function

What it means

The deauth-callback endpoint (called by the providers themselves, not Uppy clients, e.g. Dropbox or OneDrive revocation notifications) requires an initialized provider instance on req.companion. If provider is falsy the request is rejected with 400 because status-code semantics for this endpoint are provider-specific.

Source

Thrown at packages/@uppy/aws-s3/src/index.ts:194

  // --------------------------------------------------------------------------
  // S3 Client Initialization
  // --------------------------------------------------------------------------

  #initS3Client(): void {
    if ('companionEndpoint' in this.opts) {
      if (typeof this.opts.companionEndpoint !== 'string') {
        throw new TypeError('companionEndpoint must be a string')
      }
      this.#s3Client = new S3Companion({
        companionEndpoint: this.opts.companionEndpoint,
      })
    } else if ('getCredentials' in this.opts) {
      if (typeof this.opts.s3Endpoint !== 'string') {
        throw new TypeError('s3Endpoint must be a string')
      }
      if (typeof this.opts.getCredentials !== 'function') {
        throw new TypeError('getCredentials must be a function')
      }
      if (this.opts.region != null && typeof this.opts.region !== 'string') {
        throw new TypeError('region must be a string')
      }

      // Mode: Temporary credentials (client-side signing)
      this.#s3Client = new S3mini({
        endpoint: this.opts.s3Endpoint,
        getCredentials: this.opts.getCredentials,
        region: this.opts.region,
      })
    } else if ('signRequest' in this.opts) {
      if (typeof this.opts.signRequest !== 'function') {
        throw new TypeError('signRequest must be a function')
      }
      // Mode: Custom signing function
      this.#s3Client = new S3mini({
        signRequest: this.opts.signRequest,

View on GitHub (pinned to 5d4dedd02a)

Solutions

  1. Ensure the provider is enabled and has key/secret configured in Companion
  2. Update or remove the webhook/deauthorization callback URL registered in the provider's developer console so it targets the correct deployment/provider route
  3. Verify the deployment's provider list matches what the provider's app expects

Example fix

// before: webhook targets a Companion without OneDrive configured
// after
companion({ providers: ['onedrive'], providerOptions: { onedrive: { key: '...', secret: '...' } } })
Defensive patterns

Strategy: validation

Validate before calling

// before registering the webhook in the provider's console, check Companion
const res = await fetch(`${companionUrl}/${provider}/deauth-callback`, { method: 'POST' })
if (res.status === 400) console.error('provider not enabled for deauth')

Prevention

When it happens

Trigger: POSTing a deauthorization webhook to a Companion instance where the named provider is not configured/enabled, or where the providerName does not resolve to an instantiated provider.

Common situations: The provider's developer app still has the webhook URL registered but Companion was reconfigured to drop that provider; pointing the provider webhook at the wrong Companion deployment; providerName typo in the webhook registration.

Related errors


AI-assisted analysis of transloadit/uppy@5d4dedd02a (2026-08-28). Data as JSON: /api/errors/1ebec0f99cd1a9be. Report an issue: GitHub.