ruvnet/ruflo · error · Error

Issue not found: ${input.issueId}

Error message

Issue not found: ${input.issueId}

What it means

Thrown by the simple (non-service) claimIssue handler in mcp-tools.ts when issueStore.get(input.issueId) returns undefined. The service-backed path (context.claimsService) is tried first; this only fires in the in-memory fallback path that has no persistence. The check precedes the already-claimed check.

Source

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

  // Try to use claims service if available
  if (context?.claimsService) {
    const claim = await context.claimsService.claimIssue(input);
    return {
      claimId: claim.id,
      issueId: claim.issueId,
      claimantId: claim.claimantId,
      claimantType: claim.claimantType,
      status: claim.status,
      claimedAt: claim.claimedAt,
      expiresAt: claim.expiresAt,
    };
  }

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

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

  const claimId = generateSecureId('claim');
  const claimedAt = new Date().toISOString();
  const expiresAt = input.expiresInMs
    ? new Date(Date.now() + input.expiresInMs).toISOString()
    : undefined;

  const claim: Claim = {
    id: claimId,
    issueId: input.issueId,
    claimantType: input.claimantType,
    claimantId: input.claimantId,
    status: 'active',

View on GitHub (pinned to 6b01dc5a68)

Solutions

  1. Ensure the issue was created via the matching createIssue/registerIssue tool in the same process.
  2. Pass a configured context.claimsService backed by a real repository so the service path handles lookup with proper persistence.
  3. List available issues first to confirm the exact ID.

Example fix

// before
await claimIssue.handler({ issueId: 'ISSUE-42', claimantId: 'alice', claimantType: 'human' });
// throws 66 if 'ISSUE-42' not in issueStore

// after — verify existence first
const list = await listIssues.handler({});
const exists = list.issues.some(i => i.id === 'ISSUE-42');
if (exists) await claimIssue.handler({ issueId: 'ISSUE-42', claimantId: 'alice', claimantType: 'human' });
Defensive patterns

Strategy: validation

Validate before calling

function issueExists(store, id) { return store.has(id); }
if (!issueExists(issueStore, input.issueId)) throw new Error(`unknown issue ${input.issueId}`);

Type guard

null

Try / catch

try { await claimIssue.handler(input, ctx); } catch (e) { if (/Issue not found/.test(e.message)) { /* create or skip */ } else throw e; }

Prevention

When it happens

Trigger: Calling claimIssue with an issueId that was never registered in the in-memory issueStore, or an ID from a different process/instance where the Map is empty.

Common situations: Using the tool without wiring up an issue store; passing a typo'd or stale ID; running against a fresh process that lost prior in-memory state; mixing ID formats (e.g., 'ISSUE-1' vs 'issue-1').

Related errors


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