yikart/AiToEarn · error · AppException

ChannelAuthRefreshTokenMissing

ChannelAuthRefreshTokenMissing

Error message

ChannelAuthRefreshTokenMissing

What it means

Kwai credential refresh was attempted without a stored refresh token; the provider cannot exchange anything for a new access token.

Source

Thrown at project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/kwai/kwai-auth.provider.ts:48

    return { url, state: input.state, redirectUri: this.config.redirectUri }
  }

  async exchangeCode(input: AuthCallbackInput): Promise<CredentialResult> {
    const callback = parseOAuthCallback(input)
    const result = await this.kwaiService.exchangeCode(callback.code)

    return {
      accessToken: result.accessToken,
      refreshToken: result.refreshToken,
      expiresAt: result.expiresAt,
      scope: result.scope,
      platformUid: result.openId,
    }
  }

  async refresh(input: RefreshCredentialInput): Promise<CredentialResult> {
    if (!input.refreshToken) {
      throw new AppException(ResponseCode.ChannelAuthRefreshTokenMissing)
    }

    const result = await this.kwaiService.refreshToken(input.refreshToken)

    return {
      accessToken: result.accessToken,
      refreshToken: result.refreshToken,
      expiresAt: result.expiresAt,
      scope: result.scope,
    }
  }

  async revoke(_input: RevokeCredentialInput): Promise<void> {
    // Kwai does not support token revocation via API
    this.logger.warn('Kwai does not support token revocation via API')
  }

  async getProfile(input: CredentialContext): Promise<PlatformAccountProfile> {

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Re-run the Kwai OAuth authorize flow to get a fresh refresh_token and persist it
  2. Confirm the Kwai app has permission/scope granting refresh tokens
  3. Check the credential save path stores result.refreshToken
  4. If the refresh token was consumed/expired, full re-auth is required
Defensive patterns

Strategy: validation

Validate before calling

if (!credential.refreshToken) {
  throw new Error('No Kwai refresh token stored; user must re-authorize the Kwai channel')
}

Type guard

function hasKwaiRefreshToken(c: { refreshToken?: string | null }): c is { refreshToken: string } {
  return typeof c.refreshToken === 'string' && c.refreshToken.length > 0
}

Try / catch

try {
  await provider.refresh(input)
} catch (e) {
  if (e.code === 'ChannelAuthRefreshTokenMissing') {
    await markChannelNeedsReauth(accountId, 'kwai')
  } else throw e
}

Prevention

When it happens

Trigger: refresh() is called with input.refreshToken falsy — the Kwai OAuth grant didn't yield a refresh token or it wasn't persisted on the credential.

Common situations: Kwai OpenAPI app not approved for offline access (refresh_token not returned); credential saved before refresh_token existed; token record truncated during storage/migration; refresh token already consumed and cleared.

Related errors


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