yikart/AiToEarn · error · NotFoundException
钱包账户不存在
Error message
钱包账户不存在
What it means
HTTP 404 NotFoundException '钱包账户不存在' thrown when the accountId in the withdraw-cash body does not resolve to a wallet account via financeService.getUserWalletAccountById (task.controller.ts:149). All prior checks (ownership, APPROVED status) passed; only the wallet lookup failed.
Source
Thrown at project/aitoearn-electron/server/src/modules/task/task.controller.ts:149
// 任务提现(创建提现数据)
@ApiOperation({ summary: '用户任务提现' })
@ApiResult({ type: Boolean })
@Post('withdraw/:id')
async withdrawCashUserTask(
@GetToken() token: TokenInfo,
@Param('id') id: string,
@Body() data: { accountId: string },
) {
const userTask = await this.userTaskService.getUserTaskInfoById(id);
if (!userTask || userTask.userId.toString() !== token.id)
throw new NotFoundException('任务不存在');
if (userTask.status !== UserTaskStatus.APPROVED)
throw new NotFoundException('任务状态不正确');
const account = await this.financeService.getUserWalletAccountById(
data.accountId,
);
if (!account) throw new NotFoundException('钱包账户不存在');
return await this.financeService.createUserWalletRecord(token.id, account, {
dataId: userTask.id,
type: UserWalletRecordType.WITHDRAW,
balance: userTask.reward, // 将 number 转换为 Decimal128
des: '任务提现',
status: UserWalletRecordStatus.WAIT,
});
}
@ApiOperation({ summary: '统计合计进行中的任务的金额总数' })
@Get('reward/amount')
@ApiResult({ type: Number })
async getTotalAmountOfDoingTasks(@GetToken() token: TokenInfo) {
return await this.taskService.getTotalAmountOfDoingTasks(token.id);
}
@ApiOperation({ summary: '获取任务的最优素材' })View on GitHub (pinned to d3aa8bea5b)
Solutions
- Fetch the user's wallet account list and use a current account id
- Ensure accountId is non-empty and correctly bound to the authenticated user
- Recreate the wallet account if it was deleted, then retry
- Validate accountId client-side before submitting the request
Example fix
// before
await api.withdrawCash(userTask.id, { accountId: cachedAccountId })
// after
const account = await api.getWalletAccounts().then(a => a[0])
await api.withdrawCash(userTask.id, { accountId: account.id }) Defensive patterns
Strategy: validation
Validate before calling
const accounts = await api.getWalletAccounts(token.id)
const account = accounts.find(a => a.id === accountId)
if (!account) throw new Error('Wallet account does not exist for this user') Type guard
function isValidAccountId(id: unknown): id is string {
return typeof id === 'string' && /^[a-f\d]{24}$/i.test(id)
} Try / catch
try {
await api.withdrawCash(userTaskId, { accountId })
} catch (e) {
if (e?.status === 404 && e?.message === '钱包账户不存在') {
// re-fetch wallet accounts and let the user pick a valid one
} else throw e
} Prevention
- Refresh wallet account list before showing the withdrawal form
- Never send an empty or undefined accountId
- Clear cached account ids after account deletion or user switch
When it happens
Trigger: POST withdraw-cash with data.accountId that has no matching user wallet account: deleted account, account of another user, or a fabricated/truncated id.
Common situations: Client caches wallet account ids after the account was deleted; UI sends an empty string or undefined accountId; multi-account users switch accounts but keep a stale accountId.
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
- 任务素材不存在
- 任务状态不正确
- No subtitle entries in response
- No response from Gemini
- Invalid subtitle data: ${z.prettifyError(result.error)}
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/7aefc9e3d1549c2a.
Report an issue: GitHub.