ruvnet/ruflo · error · Error
Claim not found for issue: ${issueId}
Error message
Claim not found for issue: ${issueId} What it means
Plain Error thrown by WorkStealingService.markStealable when repository.findByIssueId(issueId) returns null. Marking an issue stealable requires a live claim to attach steal metadata to. Note the inconsistency: the sibling steal() method returns a structured StealResult error for the same condition, but markStealable throws.
Source
Thrown at v3/@claude-flow/claims/src/application/work-stealing-service.ts:211
* monotonic across the federation. Otherwise fall back to wall clock.
*/
private nowMs(): number {
if (this.hlc) return this.hlc.now().physicalMs;
return Date.now();
}
// ===========================================================================
// Mark Stealable
// ===========================================================================
/**
* Mark work as stealable with the given reason
*/
async markStealable(issueId: IssueId, info: StealableInfo): Promise<void> {
const claim = await this.repository.findByIssueId(issueId);
if (!claim) {
throw new Error(`Claim not found for issue: ${issueId}`);
}
// Check if already stealable
if (claim.stealInfo) {
return; // Already marked
}
// Check grace period protection
if (this.isInGracePeriod(claim)) {
throw new Error(`Claim is still in grace period`);
}
// Check progress protection
if (this.isProtectedByProgress(claim)) {
throw new Error(`Claim is protected by progress (${claim.progress}%)`);
}
// Update claim with stealable infoView on GitHub (pinned to 6b01dc5a68)
Solutions
- Confirm a claim exists (getStealable or a findByIssueId check) before marking.
- Skip ids without claims in auto-mark loops rather than throwing.
- Correct or prune the issueId list fed to the marker.
- Re-claim the issue if it should genuinely be stealable work.
Example fix
// before await workStealing.markStealable(issueId, info); // throws // after const claim = await repo.findByIssueId(issueId); if (claim) await workStealing.markStealable(issueId, info);
Defensive patterns
Strategy: validation
Validate before calling
const claim = await repository.findByIssueId(issueId); if (!claim) return; // nothing to mark await workStealing.markStealable(issueId, info);
Try / catch
try {
await workStealing.markStealable(issueId, info);
} catch (e) {
// plain Error; match on the known prefix
if (e instanceof Error && /Claim not found for issue/.test(e.message)) return;
throw e;
} Prevention
- In auto-mark loops, skip ids without claims instead of throwing.
- Keep the issueId feed pruned of released/expired issues.
- Prefer the structured steal() return path where available; track the markStealable throw as a known inconsistency.
When it happens
Trigger: Calling markStealable on an issue that was never claimed; after the claim was released/expired; an auto-marker scanning a list that includes unclaimed or released issue ids; wrong issueId.
Common situations: autoMarkStealable iterating over a broad id set that contains released issues; cross-store id mismatch; stale id list.
Related errors
- Claim is still in grace period
- Claim is protected by progress (${claim.progress}%)
- No steal to contest - issue was not recently stolen
- Contest has already been resolved
- Contest window has expired
AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12).
Data as JSON: /api/errors/ea606350f502f3ee.
Report an issue: GitHub.