yikart/AiToEarn · error · AppException

ChannelAuthRefreshTokenMissing

ChannelAuthRefreshTokenMissing

Error message

ChannelAuthRefreshTokenMissing

What it means

ChannelAuthRefreshTokenMissing is thrown by the Pinterest auth provider's refresh() when input.refreshToken is missing. Pinterest token refresh requires the refresh token issued during OAuth; without it the provider cannot obtain a new accessToken and fails fast with this error.

Source

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

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

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

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

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

    const result = await this.pinterestService.refreshAccessToken(input.refreshToken)

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

  async revoke(input: RevokeCredentialInput): Promise<void> {
    try {
      await this.pinterestService.revokeToken(input.accessToken)
    }
    catch (err) {
      this.logger.warn(err, 'Failed to revoke Pinterest token')

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Confirm the Pinterest OAuth flow persists the refresh_token returned by the token endpoint
  2. Re-run the channel connection flow to issue a new refresh token
  3. Audit stored Pinterest credentials for null refresh_token and re-auth those channels

Example fix

// before
await pinterestAuthProvider.refresh({ accessToken }) // throws ChannelAuthRefreshTokenMissing
// after
if (!credential.refreshToken) await reconnectChannel(credential.channelId)
await pinterestAuthProvider.refresh({ accessToken, refreshToken: credential.refreshToken })
Defensive patterns

Strategy: validation

Validate before calling

if (!credential.refreshToken) {
  throw new Error('Pinterest credential missing refresh token; reconnect the channel')
}
await pinterestAuthProvider.refresh({ accessToken: credential.accessToken, refreshToken: credential.refreshToken })

Type guard

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

Try / catch

try {
  await pinterestAuthProvider.refresh(input)
} catch (e) {
  if (e instanceof AppException && e.code === ResponseCode.ChannelAuthRefreshTokenMissing) {
    await markChannelNeedsReauth(channelId)
  } else throw e
}

Prevention

When it happens

Trigger: Calling refresh() on a Pinterest credential whose refreshToken field is null/undefined/empty string — credentials created without the refresh token persisted, or tokens cleared after user revocation.

Common situations: Pinterest connect flow not persisting refresh_token; manual DB seeding with access token only; Pinterest revoked the token so the stored refresh token was purged; account reconnected under a different app losing the token.

Related errors


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