{"record":{"id":"97c7725db129fe87","repo":"yikart/AiToEarn","slug":"cannot-submit-task-in-current-status","errorCode":null,"errorMessage":"Cannot submit task in current status","messagePattern":"Cannot submit task in current status","errorType":"validation","errorClass":"BadRequestException","httpStatus":400,"severity":"warning","filePath":"project/aitoearn-electron/server/src/modules/task/user-task.service.ts","lineNumber":133,"sourceCode":"    }\n  }\n\n  /**\n   * 提交任务\n   * @param userTask\n   * @param data\n   * @returns\n   */\n  async submitTask(userTask: UserTask, data: SubmitTaskDto): Promise<UserTask> {\n    const userTaskD = await this.userTaskModel.findById(userTask.id);\n\n    // 只有拒绝和进行中的才能提交\n    if (\n      ![UserTaskStatus.REJECTED, UserTaskStatus.DODING].includes(\n        userTask.status,\n      )\n    ) {\n      throw new BadRequestException('Cannot submit task in current status');\n    }\n\n    userTaskD.submissionUrl = data.submissionUrl;\n    userTaskD.screenshotUrls = data.screenshotUrls;\n    userTaskD.qrCodeScanResult = data.qrCodeScanResult;\n    userTaskD.submissionTime = new Date();\n    userTaskD.status = UserTaskStatus.PENDING;\n\n    // 保存\n    return userTaskD.save();\n  }\n\n  /**\n   *  获取用户的任务列表\n   * @param userId\n   * @param query\n   * @returns\n   */","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-electron/server/src/modules/task/user-task.service.ts#L115-L151","documentation":"HTTP 400 BadRequestException 'Cannot submit task in current status' thrown by UserTaskService.submitTask (user-task.service.ts:133). Only user tasks in REJECTED or DODING status may be submitted; any other status (e.g. PENDING audit, APPROVED) is rejected to enforce the task state machine.","triggerScenarios":"Calling the submit endpoint when userTask.status is PENDING (already submitted and awaiting audit) or APPROVED — typically a double submit or submit after approval.","commonSituations":"User double-clicks the submit button creating two submissions; client retries on a timeout after the first submit succeeded; attempting to re-edit an already-approved task.","solutions":["Check userTask.status is REJECTED or DODING before calling submit","Disable the submit button after the first successful call (idempotency guard in UI)","If a retry is needed after a network failure, re-fetch the task status first — if it became PENDING the submit already went through","Wait for the auditor to reject the submission before re-submitting"],"exampleFix":"// before\nawait api.submitTask(userTaskId, data) // may throw if PENDING\n// after\nconst ut = await api.getUserTaskInfo(userTaskId)\nif (['REJECTED', 'DODING'].includes(ut.status)) await api.submitTask(userTaskId, data)","handlingStrategy":"validation","validationCode":"const ut = await api.getUserTaskInfo(userTaskId)\nif (!['REJECTED', 'DODING'].includes(ut.status)) {\n  throw new Error(`Submission not allowed in status ${ut.status}`)\n}","typeGuard":"function canSubmit(ut: UserTask): boolean {\n  return ut.status === 'REJECTED' || ut.status === 'DODING'\n}","tryCatchPattern":"try {\n  await api.submitTask(userTaskId, data)\n} catch (e) {\n  if (e?.status === 400 && e?.message === 'Cannot submit task in current status') {\n    // likely a duplicate submit: re-fetch status; it may already be PENDING\n  } else throw e\n}","preventionTips":["Disable the submit control immediately after a successful call","Make retries idempotent: check status first, submit only if REJECTED/DODING","Do not allow editing approved tasks; open a new application instead"],"tags":["http-400","state-machine","duplicate-submit"],"backgroundTag":"invalid-resource-state","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}