yikart/AiToEarn · error · AppException
AccountNotFound
AccountNotFound
Error message
AccountNotFound
What it means
getAccountOptionContext loads the account with getByIdAndUserId(accountId, userId) to scope option-field operations to the caller's own account. If no account matches both the id and the user id (nonexistent, deleted, or owned by someone else), it throws AccountNotFound. This is deliberately indistinguishable between 'not exists' and 'not yours'.
Source
Thrown at project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/platforms.service.ts:151
return {
field: source.field,
label: source.label,
description: source.description,
valueType: source.valueType,
requiresAccount: source.requiresAccount,
filterSchema: source.filterSchema
? z.toJSONSchema(source.filterSchema, { ...zodToJsonSchemaOptions, io: 'input' }) as PublishOptionJsonSchemaView
: undefined,
createSchema: source.createSchema
? z.toJSONSchema(source.createSchema, { ...zodToJsonSchemaOptions, io: 'input' }) as PublishOptionJsonSchemaView
: undefined,
}
}
private async getAccountOptionContext(userId: string, accountId: string, field: string) {
const account = await this.accountRepository.getByIdAndUserId(accountId, userId)
if (!account) {
throw new AppException(ResponseCode.AccountNotFound)
}
if (account.relayAccountRef) {
throw new RelayAccountException(account.relayAccountRef, accountId)
}
const provider = this.registry.getPublishOptions(account.type)
if (!provider) {
throw new AppException(ResponseCode.ChannelPlatformOperationNotSupported, {
platform: account.type,
field,
})
}
const source = provider.listSources().find(item => item.field === field)
if (!source) {
throw new AppException(ResponseCode.ChannelPlatformOperationNotSupported, {
platform: account.type,
field,View on GitHub (pinned to d3aa8bea5b)
Solutions
- Refresh the account list (GET accounts for the current user) and use a fresh accountId before retrying.
- Verify the accountId belongs to the authenticated user; never use ids from other users or environments.
- Handle this code by removing the stale account from local state and prompting re-selection.
- If the account should exist, check whether it was deleted by a cleanup job or disconnect flow and re-authenticate the channel.
Example fix
// before
await api.post(`/accounts/${staleAccountId}/options/${field}/values`, data)
// after
const accounts = await api.get('/accounts')
const account = accounts.find(a => a.id === staleAccountId)
if (!account) {
await refreshAccountSelection()
return
}
await api.post(`/accounts/${account.id}/options/${field}/values`, data) Defensive patterns
Strategy: try-catch
Validate before calling
const accounts = await api.get('/accounts')
if (!accounts.some(a => a.id === accountId)) {
await promptAccountReselection()
return
} Type guard
function ownsAccount(accounts: Account[], accountId: string): boolean {
return accounts.some(a => a.id === accountId)
} Try / catch
try {
return await api.createAccountValue(accountId, field, data)
} catch (e) {
if (e instanceof AppException && e.code === ResponseCode.AccountNotFound) {
await refreshAccounts()
throw new RetryableError('Account list was stale; refreshed')
}
throw e
} Prevention
- Always derive accountId from a fresh list of the current user's accounts.
- Never hardcode or copy account ids between users/environments.
- Clear cached account selections after disconnect/delete operations.
- Treat AccountNotFound as 'refresh and re-select', not a retryable server fault.
When it happens
Trigger: Calling option-related endpoints (createAccountValue, list option sources) with an accountId that does not exist, was deleted, was disconnected, or belongs to a different user — the repository returns null and the code throws.
Common situations: A stale accountId cached in the client after the account was removed/reconnected; copying an accountId from another user/workspace; a test fixture id used in production; race where the account was deleted between listing and the follow-up call.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/2ab366b4db8cbb3f.
Report an issue: GitHub.