yikart/AiToEarn · error · AppException

ChannelAccessTokenFailed

ChannelAccessTokenFailed

Error message

ResponseCode.ChannelAccessTokenFailed

What it means

toCredentialContext throws ChannelAccessTokenFailed (AppException, ResponseCode.ChannelAccessTokenFailed) when a CredentialResult obtained from a platform integration during the auth callback has an empty/missing accessToken. It is a defensive boundary between the platform integration result and the CredentialContext used to persist credentials — an integration returned success-shaped data without a token, which must never be stored.

Source

Thrown at project/aitoearn-backend/apps/aitoearn-server/src/core/channels/auth/auth.service.ts:793

    source: string,
  ): Promise<void> {
    await this.eventStream.emit(
      EventStream.Channels,
      EventTopic.ChannelsAccountConnected,
      { userId, accountId, platform },
      { source },
    )
  }

  private shouldReassignDouyinAccount(source: string, platform: AccountType, credential: CredentialResult) {
    return source === 'auth'
      && platform === AccountType.Douyin
      && credential.callbackResponseType === AuthCallbackResponseType.Json
  }

  private toCredentialContext(credential: CredentialResult): CredentialContext {
    if (!credential.accessToken) {
      throw new AppException(ResponseCode.ChannelAccessTokenFailed)
    }

    return {
      accessToken: credential.accessToken,
      refreshToken: credential.refreshToken,
      expiresAt: credential.expiresAt,
      scope: credential.scope,
      platformUid: credential.platformUid,
    }
  }

  getPlatformAuthViewFields(platform: AccountType): Pick<AuthViewFields, 'platformDisplayName' | 'platformLogoUrl'> {
    const integration = this.registry.get(platform)
    const locale = getLocale()
    return {
      platformDisplayName: integration.metadata.displayName[locale],
      platformLogoUrl: integration.metadata.logoUrl,
    }

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Inspect the integration's token-exchange code and log the raw platform response to see why accessToken is missing.
  2. Verify the OAuth app's redirect URI, client id/secret, and callbackResponseType config match the platform console settings.
  3. Update the platform integration if the provider changed its token response format (API version drift).
  4. Catch this at the callback layer and return a clear 'authorization failed, please retry' to the user rather than persisting partial credentials.

Example fix

// before
const ctx = toCredentialContext(credential) // throws ChannelAccessTokenFailed
// after
if (!credential.accessToken) {
  throw new AppException(ResponseCode.ChannelAccessTokenFailed, { platform, raw: rawResponse })
}
const ctx = toCredentialContext(credential)
Defensive patterns

Strategy: validation

Validate before calling

if (!credential || typeof credential.accessToken !== 'string' || credential.accessToken.length === 0) {
  throw new AppException(ResponseCode.ChannelAccessTokenFailed, { platform })
}

Type guard

function hasAccessToken(c: unknown): c is { accessToken: string } {
  return !!c && typeof (c as any).accessToken === 'string' && (c as any).accessToken.length > 0
}

Try / catch

try {
  await completeAuth(sessionId, credential)
} catch (e) {
  if (e instanceof AppException && e.code === ResponseCode.ChannelAccessTokenFailed) {
    return res.status(502).json({ message: 'Authorization failed at the platform, please retry' })
  }
  throw e
}

Prevention

When it happens

Trigger: A channel integration's auth callback parsing produces a CredentialResult with no accessToken (platform returned an error payload the integration didn't map, mis-parsed response body, callbackResponseType mismatch e.g. expecting Json but receiving a redirect, or truncated query params in the OAuth redirect).

Common situations: Platform changed its OAuth callback payload shape after an API version update; wrong redirect URI config causing the code exchange to return an error body; Douyin/WeChat returning error codes the integration ignores; testing with a stub integration that returns partial credentials.

Related errors


AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31). Data as JSON: /api/errors/cd5d4684aefb806b. Report an issue: GitHub.