transloadit/uppy · error · Error

Missing access_token

Error message

Missing access_token

What it means

When a Dropbox access token expires, Companion refreshes it by POSTing grant_type=refresh_token to Dropbox's token endpoint. If the JSON response does not contain a non-empty access_token string, this error is thrown, indicating the refresh failed in an unexpected way (Dropbox usually returns an error status, which got.stream/retry would surface separately).

Source

Thrown at packages/@uppy/companion/src/server/provider/dropbox/index.ts:375

    clientSecret: string | undefined
    refreshToken: string
  }): Promise<{ accessToken: string }> {
    return this.#withErrorHandling(
      'provider.dropbox.token.refresh.error',
      async () => {
        const tokenRes = await getOauthClient()
          .post('token', {
            form: {
              refresh_token: refreshToken,
              grant_type: 'refresh_token',
              client_id: clientId,
              client_secret: clientSecret,
            },
          })
          .json<{ access_token?: unknown }>()
        const accessToken = tokenRes.access_token
        if (typeof accessToken !== 'string' || accessToken.length === 0) {
          throw new Error('Missing access_token')
        }
        return { accessToken }
      },
    )
  }

  async #withErrorHandling<T>(tag: string, fn: () => Promise<T>): Promise<T> {
    return withProviderErrorHandling({
      fn,
      tag,
      providerName: Dropbox.oauthProvider,
      isAuthError: (response) => response.statusCode === 401,
      getJsonErrorMessage: (body) => {
        if (!isRecord(body)) return undefined
        const summary = body['error_summary']
        return typeof summary === 'string' ? summary : undefined
      },
    })

View on GitHub (pinned to 5d4dedd02a)

Solutions

  1. Have the user disconnect and reconnect Dropbox so a fresh refresh token is issued
  2. Verify the Dropbox app key/secret configured in Companion match the app that issued the refresh token
  3. Check Companion logs for the underlying Dropbox response around the refresh call
  4. If it persists, inspect the raw token endpoint response (Dropbox may have changed the payload shape)
Defensive patterns

Strategy: fallback

Type guard

function isMissingTokenError(err: unknown): boolean {
  return err instanceof Error && err.message === 'Missing access_token'
}

Try / catch

try {
  await provider.download({ id })
} catch (err) {
  if (isMissingTokenError(err)) {
    await provider.logout() // clears stale refresh token
    redirectUserToReconnectProvider()
    return
  }
  throw err
}

Prevention

When it happens

Trigger: Dropbox's OAuth token endpoint returning 200 with a body lacking access_token (malformed/changed response), a refresh token that was revoked or expired so Dropbox returns an error payload, or clock/env issues causing Dropbox to respond with an auth error body.

Common situations: User revoked the app's access in Dropbox settings, the app's refresh token was invalidated by switching app keys, Dropbox API behavior change, or long-lived offline tokens expiring past the 90-day inactivity window.

Related errors


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