paperclipai/paperclip · error

Name a different agent to review this task. A worker cannot…

Error message

Name a different agent to review this task. A worker cannot review its own completion.

What it means

Within needs_review handling, each actionable agent-owned attention request must name a reviewer other than the reporting run's own agent. If targetAgentId equals run.agentId, the agent is attempting to review its own work, which the control plane forbids, and this error is thrown.

Solutions

  1. Set targetAgentId to a different agent in the same company (e.g. a designated reviewer agent).
  2. If only one agent exists, request a human reviewer (ownerClass other than 'agent') or report done/blocked instead.
  3. Fix adapter logic that defaults targetAgentId to the reporting agent's own ID.
  4. Look up reviewer agents in the company roster before building the attention request.

Example fix

// before
attentionRequests.push({ ownerClass: "agent", targetAgentId: run.agentId });
// after
const reviewer = pickReviewerAgentExcluding(run.agentId);
attentionRequests.push({ ownerClass: "agent", targetAgentId: reviewer.id });
Defensive patterns

Strategy: validation

Validate before calling

for (const r of result.attentionRequests) {
  if (r.ownerClass === "agent" && r.targetAgentId === run.agentId) {
    throw new Error("cannot name the reporting agent as its own reviewer");
  }
}

Type guard

const namesExternalReviewer = (r: { ownerClass: string; targetAgentId?: string }, selfAgentId: string): boolean => r.ownerClass !== "agent" || (!!r.targetAgentId && r.targetAgentId !== selfAgentId);

Try / catch

try { await reportCompletion({ runId, result }); } catch (e) { if (e.message.startsWith("Name a different agent")) { swapReviewerToDistinctAgent(result.attentionRequests, run.agentId); return reportCompletion({ runId, result }); } throw e; }

Prevention

When it happens

Trigger: An attention request with ownerClass 'agent' whose targetAgentId is identical to the completing run's agentId, submitted with a needs_review completion report.

Common situations: Adapters auto-filling targetAgentId from the current agent's ID; agents listing themselves as reviewer because no teammate was configured; template code copying run.agentId into the request.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18). Data as JSON: /api/errors/26fc2981e16405d3. Report an issue: GitHub.

Appendix: source

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

  if (issue.executionState?.status === "pending") {
    return `Completion report accepted; the task's configured review stage is still pending. Explain the required review on [this task](/issues/${issue.identifier ?? issue.id}); do not say the task is done.`;
  }
  const readiness = await issueService(db).getDependencyReadiness(issue.id, db);
  if (readiness.unresolvedBlockerCount > 0) {
    return `Completion report accepted; this task still has unresolved dependencies. Explain the blockers on [this task](/issues/${issue.identifier ?? issue.id}); do not say the task is done.`;
  }
  if (
    result.reportedWorkDisposition === "needs_review" &&
    signals.actionableAttentionRequests.length === 0
  ) {
    throw new Error(
      "needs_review requires a concrete decision and a named reviewer in attentionRequests. Continue unfinished work or checks; report done when complete. Paperclip will not create an automatic completion approval.",
    );
  }
  for (const request of signals.actionableAttentionRequests) {
    if (request.ownerClass !== "agent") continue;
    if (request.targetAgentId === run.agentId) {
      throw new Error("Name a different agent to review this task. A worker cannot review its own completion.");
    }
    if (!request.targetAgentId || !/^[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i.test(request.targetAgentId)) {
      throw new Error("Name the reviewer's exact agent ID in targetAgentId.");
    }
    const reviewer = await db.select().from(agents).where(and(
      eq(agents.id, request.targetAgentId), eq(agents.companyId, run.companyId),
    )).limit(1).then((rows) => rows[0]);
    if (!reviewer || !(await evaluateAgentInvokabilityFromDb(db, reviewer)).invokable) {
      throw new Error("The named reviewer is not available in this company. Choose an available reviewer or report the concrete blocker.");
    }
  }
  return "Completion report accepted. Task status will be committed after this turn and workspace finalization finish. Describe the completed work and any explicitly requested reviewer action; do not claim an approval is needed unless one was requested.";
}

View on GitHub (pinned to 3f1d897a7c)