yikart/AiToEarn · error · RelayAuthException

RelayAuthException

Error message

RelayAuthException

What it means

getAuthSessionResult refuses to serve auth session results when the relay client service is enabled; RelayAuthException signals that session polling must go through the Relay flow instead of this local Redis-backed path. It enforces the environment separation between Relay mode and direct channel auth.

Source

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

        type: identity.platform,
        uid: identity.platformUid,
        account: accountIdentity,
      })
      if (account?.userId) {
        owners.add(account.userId)
      }
    }

    return Array.from(owners)
  }

  async getAuthSessionResult(
    userId: string,
    platform: AccountType | undefined,
    sessionId: string,
  ): Promise<AuthSessionResult> {
    if (this.relayClientService?.enabled) {
      throw new RelayAuthException()
    }
    const session = await this.redis.getChannelAuthSession<AuthSession>(sessionId)
    if (!session || session.userId !== userId) {
      throw new AppException(ResponseCode.ChannelAuthSessionInvalid)
    }
    if (this.isSessionExpired(session)) {
      throw new AppException(ResponseCode.ChannelAuthSessionInvalid)
    }
    if (platform && session.platform !== platform) {
      throw new AppException(ResponseCode.ChannelAuthPlatformMismatch)
    }
    const expiresAt = this.getSessionExpiresAt(session)

    return {
      sessionId: session.id,
      status: session.status,
      requiresSelection: session.status === ChannelAuthSessionStatus.Pending
        && Boolean(session.selectableAccounts?.length),

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Use the Relay endpoint/SDK to obtain auth results instead of the direct session API
  2. Disable the relay client in environments that rely on direct channel auth polling
  3. Point the client at the correct environment (aitoearn.cn vs aitoearn.ai) matching the key type

Example fix

// before
const result = await api.getAuthSessionResult(userId, platform, sessionId) // 409/500 RelayAuthException
// after
const result = relayEnabled
  ? await relayClient.getAuthResult(sessionId)
  : await api.getAuthSessionResult(userId, platform, sessionId)
Defensive patterns

Strategy: fallback

Validate before calling

const useRelay = relayClientService?.enabled === true
if (useRelay) { /* route to relay flow instead of direct session API */ }

Type guard

function isRelayAuthException(e): e is RelayAuthException { return e?.name === 'RelayAuthException' }

Try / catch

try {
  return await api.getAuthSessionResult(userId, platform, sessionId)
} catch (e) {
  if (isRelayAuthException(e)) return relayClient.getAuthResult(sessionId)
  throw e
}

Prevention

When it happens

Trigger: Calling getAuthSessionResult (direct REST polling of an auth session) while this server instance has RelayAuthClientService enabled (RELAY mode configured).

Common situations: Deployment misconfiguration: server started with Relay enabled but an old client/integration still polls the direct session endpoint; mixing China/international or relay/direct environments; tests written against direct auth running in a relay-enabled environment.

Related errors


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