transloadit/uppy · warning · TypeError

One of options `companionEndpoint`, `signRequest`, or `getCr

Error message

One of options `companionEndpoint`, `signRequest`, or `getCredentials` is required

What it means

The list controller (directory listing) rejects the request with 400 when no provider instance exists, or when an id parameter is present but is not a string (e.g. an array from a repeated query/path param).

Source

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

        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,
      })
    } else {
      throw new TypeError(
        'One of options `companionEndpoint`, `signRequest`, or `getCredentials` is required',
      )
    }
  }

  // --------------------------------------------------------------------------
  // Upload Entry Point
  // --------------------------------------------------------------------------

  #upload = async (fileIDs: string[]): Promise<void> => {
    if (fileIDs.length === 0) return

    const files = this.uppy.getFilesByIds(fileIDs)
    const filesToUpload = filterFilesToUpload(files)
    const filesToEmit = filterFilesToEmitUploadStarted(filesToUpload)

    this.uppy.emit('upload-start', filesToEmit)

View on GitHub (pinned to 5d4dedd02a)

Solutions

  1. Ensure the id (when present) is passed as a single string value
  2. Confirm the provider is enabled with key/secret in companionOptions
  3. Send a valid provider session token with the request

Example fix

// before
fetch(`/companion/box/list/?id[]=root&id[]=other`)
// after
fetch(`/companion/box/list/?id=root`)
Defensive patterns

Strategy: validation

Validate before calling

const qs = id ? `?id=${encodeURIComponent(id)}` : ''
if (Array.isArray(id)) throw new Error('id must be a single string')
await fetch(`${companionUrl}/${provider}/list${qs}`)

Type guard

const isStringOrUndefined = (v: unknown): v is string | undefined =>
  v === undefined || typeof v === 'string'

Prevention

When it happens

Trigger: Calling /list with ?id[]=a&id[]=b producing a non-string id; or listing for a provider that is not configured/enabled on the Companion server so provider is falsy.

Common situations: Custom frontend code passing array params; provider name mismatch between client and server; missing provider credentials so the instance was never created.

Related errors


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