{"record":{"id":"5b15af8b5b71529e","repo":"toeverything/AFFiNE","slug":"copilot-transcription-job-not-found-5b15af","errorCode":"copilot_transcription_job_not_found","errorMessage":"Transcription job not found.","messagePattern":"Transcription job not found\\.","errorType":"exception","errorClass":"CopilotTranscriptionJobNotFound","httpStatus":400,"severity":"error","filePath":"packages/backend/server/src/plugins/copilot/transcript/service.ts","lineNumber":477,"sourceCode":"\n    await this.retry.enqueuePendingTask(task.id, payload, generation, null);\n    this.publishTaskChanged(workspaceId, task.id, AiJobStatus.pending);\n\n    return { id: task.id, status: AiJobStatus.pending, infos };\n  }\n\n  async retryTask(userId: string, workspaceId: string, taskId: string) {\n    return await this.retry.retryTask(userId, workspaceId, taskId);\n  }\n\n  async settleTask(userId: string, workspaceId: string, taskId: string) {\n    const task = await this.models.copilotTranscriptTask.getWithUser(\n      userId,\n      workspaceId,\n      taskId\n    );\n    if (!task) {\n      throw new CopilotTranscriptionJobNotFound();\n    }\n    if (task.status === 'failed') {\n      throw new BadRequestException(\n        'Failed transcript tasks cannot be settled'\n      );\n    }\n    if (task.status !== 'ready' && task.status !== 'settled') {\n      return null;\n    }\n\n    if (task.status === 'settled') {\n      return taskToJob(task);\n    }\n\n    const settled = await this.models.copilotTranscriptTask.settle(task.id);\n    return taskToJob(settled);\n  }\n","sourceCodeStart":459,"sourceCodeEnd":495,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/591f874dad30887a80143a061a44bd3ca7ee3299/packages/backend/server/src/plugins/copilot/transcript/service.ts#L459-L495","documentation":"Thrown by CopilotTranscriptService.settleTask when models.copilotTranscriptTask.getWithUser(userId, workspaceId, taskId) returns null: no transcription task exists with that taskId, or the task exists but is scoped to a different user/workspace. It is a UserFriendlyError with HTTP class bad_request and code copilot_transcription_job_not_found.","triggerScenarios":"Calling the transcript settle API/mutation with a taskId that was never created, was deleted, or belongs to another user or workspace; using a taskId cached from a previous session or from a different workspace in multi-workspace clients.","commonSituations":"Client caches a taskId across sessions after the task row was cleaned up; wrong workspaceId passed alongside a valid taskId; task was replaced by a new upload/retry and the caller still references the old id.","solutions":["List the user's transcript jobs for the workspace first and settle an id returned by that list","Verify both userId and workspaceId match the task's owner - getWithUser filters by all three keys","If the task was recreated by retryTask, use the fresh taskId/job object it returns instead of the stale one","If you operate the database, confirm the row exists in the copilot_transcript_task table"],"exampleFix":"// before\nconst job = await client.settleTranscriptTask({ workspaceId, taskId: cachedTaskId });\n\n// after\nconst jobs = await client.listTranscriptJobs(workspaceId);\nconst task = jobs.find(j => j.id === cachedTaskId);\nif (!task) throw new Error('stale task id - refresh job list');\nconst job = await client.settleTranscriptTask({ workspaceId, taskId: task.id });","handlingStrategy":"validation","validationCode":"const jobs = await client.listTranscriptJobs(workspaceId);\nconst task = jobs.find(j => j.id === taskId && j.workspaceId === workspaceId);\nif (!task) {\n  // refresh cached ids; do not call settle\n  throw new Error(`transcript task ${taskId} not found for this user/workspace`);\n}\nawait client.settleTranscriptTask({ workspaceId, taskId });","typeGuard":"const isTranscriptJob = (j: unknown): j is TranscriptJob =>\n  typeof j === 'object' && j !== null &&\n  typeof (j as TranscriptJob).id === 'string' &&\n  typeof (j as TranscriptJob).status === 'string';","tryCatchPattern":"try {\n  await settle(taskId);\n} catch (e) {\n  if (e instanceof GraphQLAuthProviderError && e.code === 'copilot_transcription_job_not_found') {\n    cachedTaskIds.delete(taskId); // drop stale reference\n    await refreshJobs();\n  } else throw e;\n}","preventionTips":["Never cache transcription task ids across sessions; re-derive them from the job list","Treat task ids as scoped to (userId, workspaceId) - always send the matching workspaceId","Log the taskId and workspaceId with every settle call for quick diagnosis"],"tags":["copilot","transcription","not-found","task-id","graphql"],"backgroundTag":"entity-not-found","analyzedSha":"591f874dad30887a80143a061a44bd3ca7ee3299","analyzedAt":"2026-08-18T21:16:52.546Z","contentChangedAt":"2026-08-18T21:16:52.546Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}