{"record":{"id":"fb95840d7ee75866","repo":"ruvnet/ruflo","slug":"claimant-not-found","errorCode":"CLAIMANT_NOT_FOUND","errorMessage":"Target claimant ${to.name} not found","messagePattern":"Target claimant (.+?) not found","errorType":"error_code","errorClass":"ClaimOperationError","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/claims/src/application/claim-service.ts","lineNumber":321,"sourceCode":"      throw new ClaimOperationError(\n        'UNAUTHORIZED',\n        `Claimant ${from.name} does not own the claim on issue ${issueId}`\n      );\n    }\n\n    // Check for existing pending handoffs\n    const existingPending = claim.handoffChain?.find((h) => h.status === 'pending');\n    if (existingPending) {\n      throw new ClaimOperationError(\n        'HANDOFF_PENDING',\n        `A handoff to ${existingPending.to.name} is already pending`\n      );\n    }\n\n    // Validate 'to' claimant exists\n    const toClaimant = await this.claimantRepository.findById(to.id);\n    if (!toClaimant) {\n      throw new ClaimOperationError('CLAIMANT_NOT_FOUND', `Target claimant ${to.name} not found`);\n    }\n\n    // Create handoff record\n    const handoffId = `handoff-${randomUUID()}`;\n    const handoffRecord: HandoffRecord = {\n      id: handoffId,\n      from,\n      to,\n      reason,\n      status: 'pending',\n      requestedAt: new Date(),\n    };\n\n    // Update claim\n    claim.handoffChain = claim.handoffChain ?? [];\n    claim.handoffChain.push(handoffRecord);\n    claim.status = 'pending_handoff';\n    claim.lastActivityAt = new Date();","sourceCodeStart":303,"sourceCodeEnd":339,"githubUrl":"https://github.com/ruvnet/ruflo/blob/6b01dc5a687b26b3e218f796de45ec51f8fa9e8c/v3/@claude-flow/claims/src/application/claim-service.ts#L303-L339","documentation":"Thrown by ClaimService.requestHandoff when claimantRepository.findById(to.id) returns null. The service validates the target claimant is registered before creating a handoff record, so an unknown recipient is rejected with CLAIMANT_NOT_FOUND. This prevents handing off to a non-existent agent/human.","triggerScenarios":"Passing a 'to' Claimant whose id was never registered in the claimant repository; a typo'd id; a target agent that has been decommissioned.","commonSituations":"Handing off to an agent that hasn't been provisioned yet; referencing a human by the wrong id; the claimant repository is a different instance from the one where the target was created.","solutions":["Register the target claimant (claimantRepository.create) before requesting a handoff.","Look up the target via findById first and surface a clear error if missing.","Ensure the same claimant repository instance is used for both registration and handoff."],"exampleFix":"// before\nawait service.requestHandoff(issueId, from, { id: 'agent-v2', name: 'V2', type: 'agent' }, reason);\n// throws CLAIMANT_NOT_FOUND\n\n// after\nconst to = await claimantRepo.findById('agent-v2');\nif (!to) throw new Error('Register agent-v2 first');\nawait service.requestHandoff(issueId, from, to, reason);","handlingStrategy":"validation","validationCode":"const toClaimant = await claimantRepo.findById(to.id);\nif (!toClaimant) throw new Error(`claimant ${to.id} not registered`);","typeGuard":"null","tryCatchPattern":"try { await service.requestHandoff(issueId, from, to, reason); } catch (e) {\n  if (e instanceof ClaimOperationError && e.code === 'CLAIMANT_NOT_FOUND') { await claimantRepo.create(to); } else throw e;\n}","preventionTips":["Register claimants (agent and human) before any handoff.","Use the same claimant repository instance across registration and handoff."],"tags":["claims","ddd","handoff","claimant-not-found","typescript"],"backgroundTag":null,"analyzedSha":"6b01dc5a687b26b3e218f796de45ec51f8fa9e8c","analyzedAt":"2026-08-12T13:20:50.148Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}