yikart/AiToEarn · error · AppException

ResponseCode.ChannelAuthSelectableAccountsNotFound

ResponseCode.ChannelAuthSelectableAccountsNotFound

Error message

ChannelAuthSelectableAccountsNotFound

What it means

Thrown in AuthService.connectSelectableAccounts when the session is valid and pending but has no selectableAccounts stored. selectableAccounts are only written to the session during completeCallback when the provider returns multiple candidate accounts; without them there is nothing to select from.

Source

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

    return {
      accountId,
      connectedAccounts: session.accounts,
      callbackResponseType: credentialResult.callbackResponseType,
      ...this.getAuthViewFields(session),
    }
  }

  async connectSelectableAccounts(
    sessionId: string,
    selectedAccounts: SelectedAccountIdentity[],
  ): Promise<ConnectSelectableAccountsResult> {
    const session = await this.redis.getChannelAuthSession<AuthSession>(sessionId)
    if (!this.isAccountAuthSessionRecord(session) || this.isSessionExpired(session) || session.status !== ChannelAuthSessionStatus.Pending) {
      throw new AppException(ResponseCode.ChannelAuthSessionInvalid)
    }
    if (!session.selectableAccounts) {
      throw new AppException(ResponseCode.ChannelAuthSelectableAccountsNotFound)
    }

    const result = await this.connectSelectedAccountsForUser({
      userId: session.userId,
      platform: session.platform,
      selectableAccounts: session.selectableAccounts,
      selectedAccounts,
      groupId: session.groupId,
      source: 'auth',
      allowReassign: true,
    })

    session.status = ChannelAuthSessionStatus.Completed
    session.accountId = result.accountIds[0]
    session.accountIds = result.accountIds
    session.accounts = result.accounts
    delete session.rootCredentialId
    delete session.selectableAccounts

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Complete the provider callback first — selection is only available when the callback returned requiresSelection: true.
  2. Verify the provider adapter actually returns selectableAccounts (listSelectableAccounts) for multi-account platforms.
  3. Restart the auth flow if the session predates a code change or was created without the selection branch.
  4. In the frontend, only render/submit the selection form when the callback response had requiresSelection set.

Example fix

// before: submitting selections without requiresSelection
await post('/accounts/auth/selections', { accounts }) // any pending session

// after: gate on the callback result
if (callbackResult.requiresSelection) {
  await post('/accounts/auth/selections', { accounts: selected })
}
Defensive patterns

Strategy: validation

Validate before calling

const callback = await completeCallback(...) // earlier step
if (!callback.requiresSelection) {
  throw new Error('No selectable accounts for this session; account already connected')
}
// only then POST /accounts/auth/selections

Type guard

function hasSelectableAccounts(s: AuthSession): s is AuthSession & { selectableAccounts: PlatformSelectableAccount[] } {
  return Array.isArray(s.selectableAccounts) && s.selectableAccounts.length > 0
}

Try / catch

try {
  await connectSelectableAccounts(sessionId, selected)
}
catch (e) {
  if (getErrorCode(e) === ResponseCode.ChannelAuthSelectableAccountsNotFound) {
    showFlowOrderError('Complete the provider callback before selecting accounts')
  }
}

Prevention

When it happens

Trigger: submitSelections is called for a session whose completeCallback path connected a single account directly (no selection step stored), or a fabricated/manual POST to /accounts/auth/selections without having gone through the multi-account callback.

Common situations: Hitting the selections endpoint out of order (skipping the callback); a provider that returns one account so the selection branch never populated the session; stale session from an older flow version before selectableAccounts existed.

Related errors


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