ruvnet/ruflo · error

Issue is not claimed by

Error message

Issue ${input.issueId} is not claimed by ${input.claimantId}

What it means

Thrown by the release-claim MCP tool handler when the issue exists and is claimed, but issue.claimedBy !== input.claimantId — the caller is not the owner of the claim. This protects against one agent releasing another agent's active claim; note the comparison is on the claimant id string, so type/namespace mismatches (agent:1 vs 1) also trip it.

Solutions

  1. Release with the exact claimantId recorded in claim.claimantId (inspect the claim first)
  2. If ownership legitimately moved, complete the handoff flow so the new owner releases it
  3. If the owner is dead, use the steal flow to acquire the claim, then release it as the new owner

Example fix

// before
await releaseTool({ issueId, claimantId: 'agent-orchestrator' }); // claim held by 'agent-worker-1'

// after
const claim = await getClaimTool({ issueId });
await releaseTool({ issueId, claimantId: claim.claimantId }); // release as the recorded owner
Defensive patterns

Strategy: validation

Validate before calling

const issue = await getIssueTool({ issueId });
if (issue.claimedBy !== claimantId) {
  throw new Error(`cannot release: claim held by ${issue.claimedBy}`);
}
await releaseTool({ issueId, claimantId });

Try / catch

try { await releaseTool(input); } catch (e) { if (e instanceof Error && e.message.includes('is not claimed by')) { /* fetch real owner and escalate */ } throw e; }

Prevention

When it happens

Trigger: Calling release with a claimantId different from the one used at claim time; using 'agent:coder-1' as claimantId when the claim was stored under 'coder-1'; supervisors attempting to force-release on behalf of a worker without matching ids.

Common situations: Handoff flows where ownership moved to a new agent but the old owner still calls release; id-format drift between subsystems; well-intentioned orchestrators cleaning up worker claims with their own id.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/8d320e7e044581b2. Report an issue: GitHub.

Appendix: source

Thrown at v3/@claude-flow/claims/src/api/mcp-tools.ts:568

}> {
  if (context?.claimsService) {
    const result = await context.claimsService.releaseClaim(input);
    return {
      released: result.released,
      issueId: input.issueId,
      releasedAt: result.releasedAt,
      reason: input.reason,
    };
  }

  // Simple implementation
  const issue = issueStore.get(input.issueId);
  if (!issue) {
    throw new Error(`Issue not found: ${input.issueId}`);
  }

  if (issue.claimedBy !== input.claimantId) {
    throw new Error(`Issue ${input.issueId} is not claimed by ${input.claimantId}`);
  }

  // Find and update the claim
  for (const claim of claimStore.values()) {
    if (claim.issueId === input.issueId && claim.claimantId === input.claimantId) {
      claim.status = 'released';
      claim.lastActivityAt = new Date().toISOString();
    }
  }

  issue.claimedBy = undefined;

  return {
    released: true,
    issueId: input.issueId,
    releasedAt: new Date().toISOString(),
    reason: input.reason,
  };

View on GitHub (pinned to fa13ee4ad6)