{"record":{"id":"a9d5628b58bdbe83","repo":"paperclipai/paperclip","slug":"name-the-reviewer-s-exact-agent-id-in-targetagentid","errorCode":null,"errorMessage":"Name the reviewer's exact agent ID in targetAgentId.","messagePattern":"Name the reviewer's exact agent ID in targetAgentId\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/src/services/native-runtime/native-completion-feedback.ts","lineNumber":155,"sourceCode":"  const readiness = await issueService(db).getDependencyReadiness(issue.id, db);\n  if (readiness.unresolvedBlockerCount > 0) {\n    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.`;\n  }\n  if (\n    result.reportedWorkDisposition === \"needs_review\" &&\n    signals.actionableAttentionRequests.length === 0\n  ) {\n    throw new Error(\n      \"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.\",\n    );\n  }\n  for (const request of signals.actionableAttentionRequests) {\n    if (request.ownerClass !== \"agent\") continue;\n    if (request.targetAgentId === run.agentId) {\n      throw new Error(\"Name a different agent to review this task. A worker cannot review its own completion.\");\n    }\n    if (!request.targetAgentId || !/^[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i.test(request.targetAgentId)) {\n      throw new Error(\"Name the reviewer's exact agent ID in targetAgentId.\");\n    }\n    const reviewer = await db.select().from(agents).where(and(\n      eq(agents.id, request.targetAgentId), eq(agents.companyId, run.companyId),\n    )).limit(1).then((rows) => rows[0]);\n    if (!reviewer || !(await evaluateAgentInvokabilityFromDb(db, reviewer)).invokable) {\n      throw new Error(\"The named reviewer is not available in this company. Choose an available reviewer or report the concrete blocker.\");\n    }\n  }\n  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.\";\n}\n","sourceCodeStart":137,"sourceCodeEnd":166,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/server/src/services/native-runtime/native-completion-feedback.ts#L137-L166","documentation":"This guard in nativeCompletionFeedback validates attention requests raised by a worker agent reporting task completion. When the request names a reviewer (ownerClass 'agent') but targetAgentId is missing or is not a UUID v4-shaped string, the runtime rejects the completion feedback so the worker names a precise reviewer instead of an unresolvable target. It forces agents to supply machine-resolvable reviewer identity.","triggerScenarios":"Calling nativeCompletionFeedback (via feedback/backend) with signals.actionableAttentionRequests containing {ownerClass:'agent', targetAgentId: undefined} or a non-UUID value like 'the reviewer agent', 'agent-2', or a truncated ID.","commonSituations":"An LLM writes prose like 'request review from the QA agent' into targetAgentId instead of copying the exact UUID; agent omits targetAgentId while setting ownerClass:'agent'; model hallucinates a malformed ID.","solutions":["Copy the reviewer's exact agent ID (UUID format) from the company's agent list into targetAgentId","If no specific reviewer is needed, omit the agent-owned attention request instead of sending ownerClass:'agent' without an ID","If targeting the run's own agent is intended, note that self-review is separately rejected (line 155) — pick a different agent"],"exampleFix":"// before\n{ ownerClass: \"agent\", targetAgentId: \"qa-agent\" }\n// after\n{ ownerClass: \"agent\", targetAgentId: \"3f2a9c1e-8b4d-4a2f-9c1e-8b4d4a2f9c1e\" }","handlingStrategy":"validation","validationCode":"const UUID_RE = /^[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i;\nif (req.ownerClass === \"agent\" && (!req.targetAgentId || !UUID_RE.test(req.targetAgentId) || req.targetAgentId === run.agentId)) {\n  throw new Error(\"Set targetAgentId to a different agent's exact UUID.\");\n}","typeGuard":"const isValidAgentTarget = (r) => r.ownerClass !== \"agent\" || (typeof r.targetAgentId === \"string\" && /^[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i.test(r.targetAgentId));","tryCatchPattern":"try { await feedback(payload); } catch (e) { if (e.message.includes(\"exact agent ID\")) { /* fix targetAgentId to a valid UUID and retry */ } else throw e; }","preventionTips":["Copy reviewer UUIDs directly from the API response, never type them from memory","Keep an agent-id registry/map per company and validate references against it before sending feedback","Never leave ownerClass:'agent' requests without a targetAgentId"],"tags":["validation","uuid","agents"],"backgroundTag":"invalid-identifier-format","analyzedSha":"3f1d897a7c018d76563a21c6e39c3c9b03933622","analyzedAt":"2026-09-18T08:03:59.046Z","contentChangedAt":"2026-09-18T08:03:59.046Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}