paperclipai/paperclip · error

Completion task no longer exists.

Error message

Completion task no longer exists.

What it means

After resolving the run's nativeIssueId, nativeCompletionFeedback loads the issue row scoped to both issue ID and the run's companyId. If no row matches, the bound task has been deleted (or belongs to a different company) and the completion report is rejected. This keeps reports from mutating tasks that no longer exist or cross company boundaries.

Solutions

  1. Treat the report as obsolete: the task is gone, so discard the queued completion report.
  2. Check whether the issue was deleted (audit/activity log) before assuming a bug.
  3. Verify the run's companyId still matches the issue's companyId; re-run under the correct company if data was moved.
  4. If deletion was unintended, restore the issue and re-submit the report.
Defensive patterns

Strategy: try-catch

Validate before calling

const issue = await getIssue(run.nativeIssueId, run.companyId);
if (!issue) throw new Error(`task ${run.nativeIssueId} no longer exists in company ${run.companyId}; discard report`);

Type guard

const issueExists = (i: { id: string; companyId: string } | undefined): i is { id: string; companyId: string } => !!i;

Try / catch

try { await reportCompletion({ runId, result }); } catch (e) { if (e.message === "Completion task no longer exists.") return { status: "discarded", reason: "task deleted" }; throw e; }

Prevention

When it happens

Trigger: The issue bound to the run was deleted between run start and completion report; the run's companyId changed or the report is issued against a run from a different company; hard-deleted issues via cleanup jobs.

Common situations: Users deleting tasks while an agent run is still in flight; company-scoped data migrations or purges; agents resuming queued completion reports after an admin removed the task.

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 paperclipai/paperclip@3f1d897a7c (2026-09-18). Data as JSON: /api/errors/aa3b99c32c247b1f. Report an issue: GitHub.

Appendix: source

Thrown at server/src/services/native-runtime/native-completion-feedback.ts:44

): Promise<string> {
  const run = await db
    .select()
    .from(heartbeatRuns)
    .where(eq(heartbeatRuns.id, runId))
    .then((rows) => rows[0]);
  if (!run?.nativeIssueId)
    throw new Error("Completion report has no bound task.");
  const issue = await db
    .select()
    .from(issues)
    .where(
      and(
        eq(issues.id, run.nativeIssueId),
        eq(issues.companyId, run.companyId),
      ),
    )
    .then((rows) => rows[0]);
  if (!issue) throw new Error("Completion task no longer exists.");
  const reviewContext = readNativeReviewAssignmentContext(run.contextSnapshot);
  if (reviewContext) {
    const review = await getNativeReviewAssignment(db, {
      companyId: run.companyId, issueId: issue.id, agentId: run.agentId,
      contextSnapshot: reviewContext, allowResolvedByRunId: run.id,
    });
    if (review?.interaction.status === "pending" && result.reportedWorkDisposition !== "blocked") {
      throw new Error("Resolve your assigned review with resolve_review before finishing. If you cannot review the work, report the concrete blocker with paperclip_block.");
    }
    return review?.interaction.status === "pending"
      ? "Review blocker recorded. Paperclip will preserve the task and record the reviewer recovery action."
      : "Review report accepted. The recorded review decision controls task completion; this report cannot override it.";
  }
  const signals = normalizePrpResultSignals(result);
  if (
    result.reportedWorkDisposition === "done" &&
    (!result.completionClaim.objectiveSatisfied ||
      result.completionClaim.criteria.some(

View on GitHub (pinned to 3f1d897a7c)