transloadit/uppy · error · TypeError

companionEndpoint must be a string

Error message

companionEndpoint must be a string

What it means

In the connect flow (encodeStateAndRedirect), before redirecting the user to the provider's consent screen, Companion verifies that both providerClass and req.companion.buildURL exist. A missing providerClass means the provider is not enabled/known; a missing buildURL means URL construction config is absent. Either results in 400.

Source

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

        ...capabilities,
        resumableUploads: value,
      },
    })
  }

  #handleCancelAll = (): void => {
    this.#setResumableUploadsCapability(true)
    this.#queue.clear()
  }

  // --------------------------------------------------------------------------
  // 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,

View on GitHub (pinned to 5d4dedd02a)

Solutions

  1. Add the provider to companionOptions.providers and provide its key/secret in providerOptions
  2. Ensure server.host/companionUrl is configured so buildURL exists
  3. Restart Companion after config changes and verify the provider appears in startup logs

Example fix

// before
companion({ providers: ['dropbox'] })
// after
companion({
  providers: ['dropbox'],
  providerOptions: { dropbox: { key: '...', secret: '...' } },
  server: { host: 'https://companion.example.com' },
})
Defensive patterns

Strategy: validation

Validate before calling

if (!providersConfig.includes(provider) || !providerOptions[provider]?.key) {
  throw new Error(`provider ${provider} not fully configured`)
}

Prevention

When it happens

Trigger: Hitting /connect/:providerName when the provider lacks Companion configuration (no key/secret so it was dropped from the providers list), or when server URL options are missing so buildURL was never set on req.companion.

Common situations: Frontend requests a provider not listed in companionOptions.providers; providerOptions missing key/secret for the requested provider; incomplete server.host configuration on self-hosted Companion.

Related errors


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