ruvnet/ruflo · warning · Error

Claim is protected by progress (${claim.progress}%)

Error message

Claim is protected by progress (${claim.progress}%)

What it means

Plain Error thrown by markStealable when isProtectedByProgress(claim) is true: the claim's progress field exceeds the configured protection threshold. The intent is that work making real progress should not be taken from its owner. The message includes the current progress percentage for diagnostics.

Source

Thrown at v3/@claude-flow/claims/src/application/work-stealing-service.ts:226

    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 info
    const now = new Date();
    claim.stealInfo = {
      ...info,
      markedAt: now,
    };
    claim.stealableAt = now;

    await this.repository.update(claim);

    // Emit event
    await this.emitMarkedStealableEvent(claim, info);
  }

  // ===========================================================================
  // Steal

View on GitHub (pinned to 6b01dc5a68)

Solutions

  1. Do not mark actively-progressing work as stealable; let the owner continue.
  2. Raise the progress-protection threshold in WorkStealingConfig if your definition of 'active' permits higher progress.
  3. Ensure agents update claim.progress so real work is protected and only stalled work becomes stealable.
  4. Treat the throw as a soft skip in auto-mark loops and continue to the next candidate.

Example fix

// before
await workStealing.markStealable(issueId, info); // progress 60% -> throws

// after
const claim = await repo.findByIssueId(issueId);
if (claim.progress < progressThreshold) {
  await workStealing.markStealable(issueId, info);
}
Defensive patterns

Strategy: validation

Validate before calling

const claim = await repository.findByIssueId(issueId);
if (claim && claim.progress >= progressThreshold) {
  // actively progressing; do not steal
  return;
}
await workStealing.markStealable(issueId, info);

Try / catch

try {
  await workStealing.markStealable(issueId, info);
} catch (e) {
  if (e instanceof Error && /protected by progress/.test(e.message)) {
    // soft skip: this claim is making progress
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling markStealable on a claim whose progress has advanced past the protection threshold; auto-detection that does not account for recent progress updates; threshold misconfigured too low.

Common situations: Stale-detection heuristic keys off inactivity but ignores progress; progress is not being updated so genuinely active work looks idle; threshold too aggressive.

Related errors


AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12). Data as JSON: /api/errors/b8f8faed213f974a. Report an issue: GitHub.