yikart/AiToEarn · error · AppException
ResponseCode.AccountNotFound
ResponseCode.AccountNotFound
Error message
AccountNotFound
What it means
getAccountAuthStatus looks up the account by (accountId, userId); if none is found, AccountNotFound is thrown. This means the account does not exist for that user — a wrong id or wrong-user access produces the same result.
Source
Thrown at project/aitoearn-backend/apps/aitoearn-server/src/core/channels/auth/auth.service.ts:479
}
async markSessionFailed(sessionId: string, errorCode: number): Promise<void> {
const session = await this.redis.getChannelAuthSession<AuthSession>(sessionId)
if (!this.isAccountAuthSessionRecord(session) || this.isSessionExpired(session) || session.status !== ChannelAuthSessionStatus.Pending) {
return
}
session.status = ChannelAuthSessionStatus.Failed
session.errorCode = errorCode
delete session.rootCredentialId
delete session.selectableAccounts
await this.redis.saveChannelAuthSession(session.id, session)
}
async getAccountAuthStatus(userId: string, platform: AccountType, accountId: string) {
const account = await this.accountRepo.getByIdAndUserId(accountId, userId)
if (!account) {
throw new AppException(ResponseCode.AccountNotFound)
}
if (account.type !== platform) {
throw new AppException(ResponseCode.ChannelAuthPlatformMismatch)
}
return { status: account.status }
}
async revokeCredential(accountId: string, userId: string): Promise<void> {
const account = await this.getCredentialAccount(accountId, userId)
const credential = await this.credentialService.getCredential(accountId)
if (credential) {
const provider = this.registry.getAuth(account.type)
await provider.revoke?.({
accessToken: credential.accessToken,
refreshToken: credential.refreshToken,
platformUid: account.uid,View on GitHub (pinned to d3aa8bea5b)
Solutions
- Verify the accountId exists for the authenticated user (list accounts first)
- Re-fetch the account list to refresh stale client caches
- Check you are hitting the correct environment (aitoearn.cn vs aitoearn.ai) for that id
Example fix
// before
const status = await api.getAccountAuthStatus(userId, platform, cachedAccountId)
// after
const accounts = await api.listAccounts(userId)
const acct = accounts.find(a => a.id === cachedAccountId)
if (!acct) { await refreshAccounts(); return }
const status = await api.getAccountAuthStatus(userId, platform, acct.id) Defensive patterns
Strategy: validation
Validate before calling
const accounts = await api.listAccounts(userId)
const exists = accounts.some(a => a.id === accountId)
if (!exists) throw new Error(`Account ${accountId} not found for user`) Type guard
function accountExists(a): a is Account { return typeof a?.id === 'string' && a.userId === currentUserId } Try / catch
try {
return await api.getAccountAuthStatus(userId, platform, accountId)
} catch (e) {
if (e.code === 'AccountNotFound') {
await syncAccounts(); return null // treat as disconnected
}
throw e
} Prevention
- Refresh account caches after disconnect/revoke operations
- Verify environment/key pairing (cn vs ai) before using stored ids
- Validate ids come from server responses, not user input
When it happens
Trigger: Querying auth status with an accountId belonging to another user, a deleted/revoked account, or a malformed/nonexistent id.
Common situations: Client cache holding account ids after the account was disconnected; switching environments (China vs international) where the id does not exist; typos or truncated ids in scripts.
Related errors
- ResponseCode.ChannelAuthSelectedAccountUnavailable
- RelayAuthException
- AccountNotFound
- fail
- Task not found
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/2334a3b7f14bbd08.
Report an issue: GitHub.