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
- Treat the report as obsolete: the task is gone, so discard the queued completion report.
- Check whether the issue was deleted (audit/activity log) before assuming a bug.
- Verify the run's companyId still matches the issue's companyId; re-run under the correct company if data was moved.
- 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
- Subscribe to issue deletion events and cancel in-flight runs' pending reports.
- Avoid hard-deleting issues that have active runs; cancel the runs first.
- Keep run.companyId and issue.companyId aligned during data migrations.
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
- Completion report has no bound task.
- Cloud runtime identity is already claimed by another…
- Could not resolve database connection from
- database-contract-unmet
- Database mode is postgres but no connection string was set…
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)