{"record":{"id":"7aefc9e3d1549c2a","repo":"yikart/AiToEarn","slug":"error-7aefc9","errorCode":null,"errorMessage":"钱包账户不存在","messagePattern":"钱包账户不存在","errorType":"http","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"project/aitoearn-electron/server/src/modules/task/task.controller.ts","lineNumber":149,"sourceCode":"\n  // 任务提现（创建提现数据）\n  @ApiOperation({ summary: '用户任务提现' })\n  @ApiResult({ type: Boolean })\n  @Post('withdraw/:id')\n  async withdrawCashUserTask(\n    @GetToken() token: TokenInfo,\n    @Param('id') id: string,\n    @Body() data: { accountId: string },\n  ) {\n    const userTask = await this.userTaskService.getUserTaskInfoById(id);\n    if (!userTask || userTask.userId.toString() !== token.id)\n      throw new NotFoundException('任务不存在');\n    if (userTask.status !== UserTaskStatus.APPROVED)\n      throw new NotFoundException('任务状态不正确');\n    const account = await this.financeService.getUserWalletAccountById(\n      data.accountId,\n    );\n    if (!account) throw new NotFoundException('钱包账户不存在');\n\n    return await this.financeService.createUserWalletRecord(token.id, account, {\n      dataId: userTask.id,\n      type: UserWalletRecordType.WITHDRAW,\n      balance: userTask.reward, // 将 number 转换为 Decimal128\n      des: '任务提现',\n      status: UserWalletRecordStatus.WAIT,\n    });\n  }\n\n  @ApiOperation({ summary: '统计合计进行中的任务的金额总数' })\n  @Get('reward/amount')\n  @ApiResult({ type: Number })\n  async getTotalAmountOfDoingTasks(@GetToken() token: TokenInfo) {\n    return await this.taskService.getTotalAmountOfDoingTasks(token.id);\n  }\n\n  @ApiOperation({ summary: '获取任务的最优素材' })","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-electron/server/src/modules/task/task.controller.ts#L131-L167","documentation":"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.","triggerScenarios":"POST withdraw-cash with data.accountId that has no matching user wallet account: deleted account, account of another user, or a fabricated/truncated id.","commonSituations":"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.","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"],"exampleFix":"// before\nawait api.withdrawCash(userTask.id, { accountId: cachedAccountId })\n// after\nconst account = await api.getWalletAccounts().then(a => a[0])\nawait api.withdrawCash(userTask.id, { accountId: account.id })","handlingStrategy":"validation","validationCode":"const accounts = await api.getWalletAccounts(token.id)\nconst account = accounts.find(a => a.id === accountId)\nif (!account) throw new Error('Wallet account does not exist for this user')","typeGuard":"function isValidAccountId(id: unknown): id is string {\n  return typeof id === 'string' && /^[a-f\\d]{24}$/i.test(id)\n}","tryCatchPattern":"try {\n  await api.withdrawCash(userTaskId, { accountId })\n} catch (e) {\n  if (e?.status === 404 && e?.message === '钱包账户不存在') {\n    // re-fetch wallet accounts and let the user pick a valid one\n  } else throw e\n}","preventionTips":["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"],"tags":["http-404","wallet","validation"],"backgroundTag":"resource-not-found","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}