transloadit/uppy · error · Error

Missing S3 object key for uploading part

Error message

Missing S3 object key for uploading part

What it means

The callback completed token exchange but req.companion.providerClass is falsy — the provider named in the URL is not registered/known to this Companion instance at this stage of the flow. Companion refuses to continue with 400 rather than crash.

Source

Thrown at packages/@uppy/aws-s3/src/S3Uploader.ts:312

    this.#options.uppy.setFileState(this.#options.file.id, {
      s3Multipart: { uploadId, key },
    })

    await this.#uploadRemainingParts(signal)
  }

  async #uploadRemainingParts(signal: AbortSignal): Promise<void> {
    for (let i = 0; i < this.#chunks.length; i++) {
      signal.throwIfAborted()
      if (this.#chunkState[i].etag) continue // already uploaded

      const chunk = this.#chunks[i]
      const partNumber = i + 1
      const chunkData = this.#data.slice(chunk.start, chunk.end)
      const chunkIndex = i // Capture for closure (cannot use for-loop variable i directly in a closure)

      if (this.#key == null) {
        throw new Error('Missing S3 object key for uploading part')
      }
      const { etag } = await this.#options.s3Client.uploadPart({
        key: this.#key,
        uploadId: this.#uploadId!,
        data: chunkData,
        partNumber,
        onProgress: (bytesUploaded: number) => {
          this.#chunkState[chunkIndex].uploaded = bytesUploaded
          this.#onProgress()
        },
        signal,
      })

      // after part finished uploading, update chunk state
      this.#chunkState[i].uploaded = chunk.size
      this.#chunkState[i].etag = etag
      this.#onProgress()

View on GitHub (pinned to 5d4dedd02a)

Solutions

  1. Confirm the provider is fully configured in companionOptions.providers plus its key/secret
  2. Check for typos in the providerName in both the frontend Uppy config and the callback URL
  3. Restart Companion after adding provider configuration
  4. If using a custom provider, verify it is properly registered in the providers map

Example fix

// before
companion({ providers: ['drive'], providerOptions: {} })
// after
companion({ providers: ['drive'], providerOptions: { drive: { key: '...', secret: '...' } } })
Defensive patterns

Strategy: validation

Validate before calling

const configured = ['drive', 'dropbox', 'box'] // mirror companionOptions.providers
if (!configured.includes(providerName)) throw new Error(`provider ${providerName} not enabled`)

Type guard

const isConfiguredProvider = (p: string): boolean =>
  configuredProviders.includes(p)

Prevention

When it happens

Trigger: providerName in the callback URL does not match any enabled provider (e.g. /connect/unknownprov/callback), or the provider was configured via grant but its Companion provider class was not loaded/enabled (missing key/secret so it was filtered out).

Common situations: Enabling a provider in grant config without providing its Companion options (key/secret); a typo in the custom provider name; upgrading Companion where a provider was renamed or moved behind a flag.

Related errors


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