toeverything/AFFiNE · error · CopilotTranscriptionJobNotFound

copilot_transcription_job_not_found

copilot_transcription_job_not_found

Error message

Transcription job not found.

What it means

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.

Source

Thrown at packages/backend/server/src/plugins/copilot/transcript/service.ts:477

    await this.retry.enqueuePendingTask(task.id, payload, generation, null);
    this.publishTaskChanged(workspaceId, task.id, AiJobStatus.pending);

    return { id: task.id, status: AiJobStatus.pending, infos };
  }

  async retryTask(userId: string, workspaceId: string, taskId: string) {
    return await this.retry.retryTask(userId, workspaceId, taskId);
  }

  async settleTask(userId: string, workspaceId: string, taskId: string) {
    const task = await this.models.copilotTranscriptTask.getWithUser(
      userId,
      workspaceId,
      taskId
    );
    if (!task) {
      throw new CopilotTranscriptionJobNotFound();
    }
    if (task.status === 'failed') {
      throw new BadRequestException(
        'Failed transcript tasks cannot be settled'
      );
    }
    if (task.status !== 'ready' && task.status !== 'settled') {
      return null;
    }

    if (task.status === 'settled') {
      return taskToJob(task);
    }

    const settled = await this.models.copilotTranscriptTask.settle(task.id);
    return taskToJob(settled);
  }

View on GitHub (pinned to 591f874dad)

Solutions

  1. List the user's transcript jobs for the workspace first and settle an id returned by that list
  2. Verify both userId and workspaceId match the task's owner - getWithUser filters by all three keys
  3. If the task was recreated by retryTask, use the fresh taskId/job object it returns instead of the stale one
  4. If you operate the database, confirm the row exists in the copilot_transcript_task table

Example fix

// before
const job = await client.settleTranscriptTask({ workspaceId, taskId: cachedTaskId });

// after
const jobs = await client.listTranscriptJobs(workspaceId);
const task = jobs.find(j => j.id === cachedTaskId);
if (!task) throw new Error('stale task id - refresh job list');
const job = await client.settleTranscriptTask({ workspaceId, taskId: task.id });
Defensive patterns

Strategy: validation

Validate before calling

const jobs = await client.listTranscriptJobs(workspaceId);
const task = jobs.find(j => j.id === taskId && j.workspaceId === workspaceId);
if (!task) {
  // refresh cached ids; do not call settle
  throw new Error(`transcript task ${taskId} not found for this user/workspace`);
}
await client.settleTranscriptTask({ workspaceId, taskId });

Type guard

const isTranscriptJob = (j: unknown): j is TranscriptJob =>
  typeof j === 'object' && j !== null &&
  typeof (j as TranscriptJob).id === 'string' &&
  typeof (j as TranscriptJob).status === 'string';

Try / catch

try {
  await settle(taskId);
} catch (e) {
  if (e instanceof GraphQLAuthProviderError && e.code === 'copilot_transcription_job_not_found') {
    cachedTaskIds.delete(taskId); // drop stale reference
    await refreshJobs();
  } else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of toeverything/AFFiNE@591f874dad (2026-08-18). Data as JSON: /api/errors/5b15af8b5b71529e. Report an issue: GitHub.