{"record":{"id":"0468cea406e0c68a","repo":"ruvnet/ruflo","slug":"max-claims-exceeded","errorCode":"MAX_CLAIMS_EXCEEDED","errorMessage":"Cannot accept handoff: claimant ${claimant.name} at max capacity","messagePattern":"Cannot accept handoff: claimant (.+?) at max capacity","errorType":"error_code","errorClass":"ClaimOperationError","httpStatus":null,"severity":"warning","filePath":"v3/@claude-flow/claims/src/application/claim-service.ts","lineNumber":380,"sourceCode":"    }\n\n    // Find pending handoff for this claimant\n    const pendingHandoff = claim.handoffChain?.find(\n      (h) => h.status === 'pending' && h.to.id === claimant.id\n    );\n\n    if (!pendingHandoff) {\n      throw new ClaimOperationError(\n        'HANDOFF_NOT_FOUND',\n        `No pending handoff found for claimant ${claimant.name}`\n      );\n    }\n\n    // Check claimant's workload\n    const currentClaimCount = await this.claimRepository.countByClaimant(claimant.id);\n    const maxClaims = claimant.maxConcurrentClaims ?? 5;\n    if (currentClaimCount >= maxClaims) {\n      throw new ClaimOperationError(\n        'MAX_CLAIMS_EXCEEDED',\n        `Cannot accept handoff: claimant ${claimant.name} at max capacity`\n      );\n    }\n\n    // Update handoff record\n    pendingHandoff.status = 'accepted';\n    pendingHandoff.resolvedAt = new Date();\n\n    // Transfer claim to new owner\n    const previousClaimant = claim.claimant;\n    claim.claimant = claimant;\n    claim.status = 'active';\n    claim.lastActivityAt = new Date();\n\n    await this.claimRepository.save(claim);\n\n    // Emit events","sourceCodeStart":362,"sourceCodeEnd":398,"githubUrl":"https://github.com/ruvnet/ruflo/blob/6b01dc5a687b26b3e218f796de45ec51f8fa9e8c/v3/@claude-flow/claims/src/application/claim-service.ts#L362-L398","documentation":"Thrown by acceptHandoff after the claim and pending handoff are validated, when the accepting claimant's active claim count (claimRepository.countByClaimant) is greater than or equal to claimant.maxConcurrentClaims, defaulting to 5 when unset. This is the capacity guard that prevents an agent from over-committing.","triggerScenarios":"An agent already at its concurrency limit accepts another handoff; maxConcurrentClaims is undefined so the default of 5 is enforced; a burst of handoffs routed to one agent pushes it over the limit between the load balancer's check and the accept call.","commonSituations":"Agent config omits maxConcurrentClaims and silently inherits 5; load balancer targeting is skewed toward one agent; long-running claims are not released promptly so the count never drops.","solutions":["Release or complete existing claims on the accepting agent before retrying the accept.","Set claimant.maxConcurrentClaims explicitly to a value that reflects the agent's real capacity.","Have the load balancer re-route the handoff target via getSwarmLoad to a less-loaded agent.","Retry the accept after a short delay during transient load spikes."],"exampleFix":"// before\nconst claimant = { id: 'agent-1', type: 'agent', name: 'worker-1' };\nawait claimService.acceptHandoff(issueId, claimant); // at capacity\n\n// after\nconst claimant = { id: 'agent-1', type: 'agent', name: 'worker-1', maxConcurrentClaims: 10 };\nconst count = await claimRepo.countByClaimant(claimant.id);\nif (count < (claimant.maxConcurrentClaims ?? 5)) {\n  await claimService.acceptHandoff(issueId, claimant);\n}","handlingStrategy":"validation","validationCode":"const max = claimant.maxConcurrentClaims ?? 5;\nconst current = await claimRepository.countByClaimant(claimant.id);\nif (current >= max) {\n  // pick a different target or wait\n  throw new Error(`${claimant.id} at capacity (${current}/${max})`);\n}\nawait claimService.acceptHandoff(issueId, claimant);","typeGuard":null,"tryCatchPattern":"try {\n  await claimService.acceptHandoff(issueId, claimant);\n} catch (e) {\n  if (e instanceof ClaimOperationError && e.code === 'MAX_CLAIMS_EXCEEDED') {\n    // re-route to a less-loaded agent or backoff and retry\n    return rerouteHandoff(issueId);\n  }\n  throw e;\n}","preventionTips":["Set maxConcurrentClaims explicitly on every Claimant rather than relying on the default 5.","Have the load balancer consult getSwarmLoad before choosing a handoff target.","Release or complete claims promptly so capacity is reclaimed."],"tags":["claims","handoff","capacity","load-balancing"],"backgroundTag":null,"analyzedSha":"6b01dc5a687b26b3e218f796de45ec51f8fa9e8c","analyzedAt":"2026-08-12T13:20:50.148Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}