yikart/AiToEarn · error · AppException

ChannelPlatformApiFailed

ChannelPlatformApiFailed

Error message

ChannelPlatformApiFailed

What it means

fetchAccessToken calls RedNote's OAuth API and expects response.data.success plus a data.access_token. When the platform responds (within the 10s timeout) but reports success=false or omits access_token, this ChannelPlatformApiFailed is thrown with the platform (RedNote) and the platform's msg as reason. It signals an upstream RedNote authorization API rejection, not a local bug.

Source

Thrown at project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/rednote/offline-qr/rednote-offline-qr.service.ts:59

    try {
      const response = await axios.post<RedNoteAccessTokenResponse>(
        this.config.accessTokenUrl,
        {
          app_key: this.config.appKey,
          nonce,
          timestamp,
          signature,
        },
        {
          headers: { 'Content-Type': 'application/json' },
          timeout: 10000,
        },
      )

      const accessToken = response.data?.data?.access_token
      if (!response.data?.success || !accessToken) {
        throw new AppException(ResponseCode.ChannelPlatformApiFailed, {
          platform: AccountType.RedNote,
          reason: response.data?.msg,
        })
      }

      return accessToken
    }
    catch (error) {
      if (error instanceof AppException) {
        throw error
      }
      throw new AppException(ResponseCode.ChannelPlatformApiFailed, {
        platform: AccountType.RedNote,
      })
    }
  }

  private generateNonce(length = 10): string {

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Read the `reason` (response.data.msg) field in the exception payload — it contains RedNote's own error message identifying the rejection cause.
  2. Verify the RedNote client key/secret and grant_type configured for the token request are correct and active in the RedNote open platform console.
  3. Ensure the authorization code being exchanged is fresh and single-use; re-run the OAuth flow to obtain a new code.
  4. Log the full response body once to confirm the response shape still matches response.data.data.access_token; update parsing if the platform changed its schema.

Example fix

// before
const accessToken = response.data?.data?.access_token
if (!response.data?.success || !accessToken) { throw ... }
// after
const accessToken = response.data?.data?.access_token
if (!accessToken) {
  this.logger.error(`RedNote token exchange failed: ${JSON.stringify(response.data)}`)
  throw new AppException(ResponseCode.ChannelPlatformApiFailed, {
    platform: AccountType.RedNote,
    reason: response.data?.msg ?? 'missing access_token',
  })
}
Defensive patterns

Strategy: try-catch

Validate before calling

// No local pre-check can fully prevent upstream rejection; verify inputs before exchange
if (!authCode) throw new Error('Missing RedNote authorization code')
if (!process.env.REDNOTE_CLIENT_KEY || !process.env.REDNOTE_CLIENT_SECRET) {
  throw new Error('RedNote client credentials not configured')
}

Type guard

function hasAccessToken(res: unknown): res is { success: boolean; data: { access_token: string } } {
  return !!res && typeof res === 'object'
    && 'success' in res && (res as any).success === true
    && !!(res as any).data?.access_token
}

Try / catch

try {
  await rednoteService.accessToken(...)
} catch (e) {
  if (e instanceof AppException && e.code === ResponseCode.ChannelPlatformApiFailed) {
    logger.error('RedNote token exchange rejected:', e.details?.reason)
    // surface re-auth requirement to user
  }
}

Prevention

When it happens

Trigger: Calling accessToken/fetchAccessToken for RedNote when the upstream API returns { success: false, msg: ... } or returns 200 without data.access_token — e.g. invalid app_id/app_secret, invalid or expired auth code, revoked grant, or RedNote-side error payload.

Common situations: Wrong RedNote client credentials in env config; exchanging an already-used or expired authorization code; RedNote app not approved/whitelisted for the token endpoint; RedNote API contract change so access_token moved out of data.data.

Related errors


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