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.selectableAccountsView on GitHub (pinned to d3aa8bea5b)
Solutions
- Complete the provider callback first — selection is only available when the callback returned requiresSelection: true.
- Verify the provider adapter actually returns selectableAccounts (listSelectableAccounts) for multi-account platforms.
- Restart the auth flow if the session predates a code change or was created without the selection branch.
- 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
- Gate the selection UI on requiresSelection from the callback response
- Complete callbacks before allowing selection submissions
- Test multi-account providers to confirm selectableAccounts is populated
- Version/bump sessions after flow logic changes
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
- ResponseCode.ChannelAuthSessionInvalid
- ResponseCode.ChannelAuthPlatformMismatch
- ResponseCode.ChannelAuthSessionCompleted
- 无效的状态码
- No response from Gemini
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/d64e2d1f54cf701c.
Report an issue: GitHub.