transloadit/uppy · warning · TypeError

region must be a string

Error message

region must be a string

What it means

The remote file download endpoint /:providerName/get/:id requires a non-empty string id parameter. This 400 is returned when the id is missing, not a string, or empty — i.e. the URL path did not include a usable file identifier.

Source

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

  // --------------------------------------------------------------------------

  #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,
      })
    } else {
      throw new TypeError(

View on GitHub (pinned to 5d4dedd02a)

Solutions

  1. Inspect the failing request URL and confirm the id segment is present and non-empty
  2. Log the file object before building the URL to confirm file.id is defined
  3. Fix proxy rewrite rules so the full path reaches Companion
  4. Regenerate/re-fetch the file listing so ids are populated

Example fix

// before
companion.fetchProviderFile(`${url}/get/${file.id}`) // file.id undefined -> /get/undefined or /get/
// after
if (!file.id) throw new Error('missing file id')
companion.fetchProviderFile(`${url}/get/${file.id}`)
Defensive patterns

Strategy: validation

Validate before calling

if (typeof file.id !== 'string' || file.id.length === 0) {
  throw new Error('cannot build get URL without a file id')
}

Type guard

const hasFileId = (f: unknown): f is { id: string } =>
  typeof (f as any)?.id === 'string' && (f as any).id.length > 0

Prevention

When it happens

Trigger: Calling /get/ with no id, an empty segment, or a malformed route (e.g. the id got stripped by a proxy rewrite). Usually hit when a stored file id is undefined and interpolated into a URL by a client.

Common situations: Persisted upload metadata (e.g. Golden Retriever or tus metadata) contains an undefined/null provider file id; a URL template bug in custom frontend code; path rewriting in a reverse proxy dropping the final segment.

Related errors


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