ruvnet/ruflo · error · Error
Issue ${issueId} is not claimed by ${this.formatClaimant(fro
Error message
Issue ${issueId} is not claimed by ${this.formatClaimant(from)} What it means
Second guard in requestHandoff(): the claim exists but its claimant is not isSameClaimant to `from`. The message names the caller's `from` claimant. This prevents an agent from initiating a handoff on behalf of a different (possibly unaware) claimant. Status is not changed to handoff-pending.
Source
Thrown at v3/@claude-flow/cli/src/services/claim-service.ts:337
}
// ==========================================================================
// Handoffs
// ==========================================================================
async requestHandoff(
issueId: string,
from: Claimant,
to: Claimant,
reason: string
): Promise<void> {
const claim = this.claims.get(issueId);
if (!claim) {
throw new Error(`Issue ${issueId} is not claimed`);
}
if (!this.isSameClaimant(claim.claimant, from)) {
throw new Error(`Issue ${issueId} is not claimed by ${this.formatClaimant(from)}`);
}
claim.status = 'handoff-pending';
claim.statusChangedAt = new Date();
claim.handoffTo = to;
claim.handoffReason = reason;
await this.saveClaims();
this.emitEvent({
type: 'issue:handoff:requested',
timestamp: new Date(),
issueId,
claimant: from,
data: { to, reason },
});
}
async acceptHandoff(issueId: string, claimant: Claimant): Promise<void> {View on GitHub (pinned to 6b01dc5a68)
Solutions
- Look up the actual current claimant and pass it as `from`.
- Restrict requestHandoff to the holder calling it itself.
- Use stable identity fields (agentId/userId) consistently across claim, release, and handoff.
Example fix
// before: coordinator guesses `from` await claims.requestHandoff(issueId, assumedFrom, to, reason); // throws // after: derive from from current claim const claim = claims.list?.().find(c => c.issueId === issueId); if (!claim) return; await claims.requestHandoff(issueId, claim.claimant, to, reason);
Defensive patterns
Strategy: validation
Validate before calling
function handoffFromCurrentHolder(claims, issueId, to, reason) {
const c = claims.list?.().find(x => x.issueId === issueId);
if (!c) throw new Error('no claim to hand off');
return claims.requestHandoff(issueId, c.claimant, to, reason);
} Prevention
- Pass the actual current claimant as `from`, not an assumed one.
- Restrict requestHandoff to the holder calling it itself when possible.
- Keep identity (agentId/userId) consistent across claim/release/handoff.
When it happens
Trigger: Agent B calling requestHandoff with from=agentA on an issue held by agentB (or vice versa); a coordinator passing the wrong `from`; stale claimant identity after an agent rename.
Common situations: Coordinator-driven handoffs that guess the current holder; mixed human/agent workflows where the `from` type is wrong; copy-paste of a claimant object between calls.
Related errors
- Handoff not addressed to ${this.formatClaimant(claimant)}
- Issue ${issueId} is not claimed by ${this.formatClaimant(cla
- Issue ${input.issueId} is not claimed by ${input.claimantId}
- UNAUTHORIZED
- No pending handoff for issue ${issueId}
AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12).
Data as JSON: /api/errors/08e3c2638f0e5eab.
Report an issue: GitHub.