ruvnet/ruflo · error · ClaimOperationError

ISSUE_NOT_FOUND

ISSUE_NOT_FOUND

Error message

Issue ${issueId} not found

What it means

Thrown by the query method getIssueStatus when issueRepository.findById(issueId) returns null. This is distinct from NOT_CLAIMED: here the Issue itself does not exist (the claim is queried only after the issue is confirmed). Use this to detect that an issue id was never imported into the issue repository.

Source

Thrown at v3/@claude-flow/claims/src/application/claim-service.ts:580

    }
  }

  // ==========================================================================
  // Queries
  // ==========================================================================

  async getClaimedBy(claimant: Claimant): Promise<IssueClaim[]> {
    return this.claimRepository.findByClaimant(claimant);
  }

  async getAvailableIssues(filters?: IssueFilters): Promise<Issue[]> {
    return this.issueRepository.findAvailable(filters);
  }

  async getIssueStatus(issueId: string): Promise<IssueWithClaim> {
    const issue = await this.issueRepository.findById(issueId);
    if (!issue) {
      throw new ClaimOperationError('ISSUE_NOT_FOUND', `Issue ${issueId} not found`);
    }

    const claim = await this.claimRepository.findByIssueId(issueId);
    const pendingHandoffs = claim?.handoffChain?.filter((h) => h.status === 'pending') ?? [];

    return {
      issue,
      claim,
      pendingHandoffs,
    };
  }

  // ==========================================================================
  // Auto-management
  // ==========================================================================

  async expireStale(maxAge: Duration): Promise<IssueClaim[]> {
    const maxAgeMs = durationToMs(maxAge);

View on GitHub (pinned to 6b01dc5a68)

Solutions

  1. Confirm the issue id exists in the issue repository before querying status.
  2. Import/sync the issue via the issue repository's create method if it legitimately should exist.
  3. Handle the error as a 404/not-found at the API boundary and inform the caller.
  4. Verify the issueId string and the repository instance backing the service.

Example fix

// before
const status = await claimService.getIssueStatus(issueId); // throws ISSUE_NOT_FOUND

// after
let status;
try {
  status = await claimService.getIssueStatus(issueId);
} catch (e) {
  if (e instanceof ClaimOperationError && e.code === 'ISSUE_NOT_FOUND') {
    return { notFound: true };
  }
  throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

const issue = await issueRepository.findById(issueId);
if (!issue) {
  return { notFound: true };
}
const status = await claimService.getIssueStatus(issueId);

Try / catch

try {
  return await claimService.getIssueStatus(issueId);
} catch (e) {
  if (e instanceof ClaimOperationError && e.code === 'ISSUE_NOT_FOUND') {
    return { notFound: true };
  }
  throw e;
}

Prevention

When it happens

Trigger: Querying an issue id that was never created/imported into issueRepository; the issue was deleted; the id belongs to a different persistence backend or tenant; typo in the id.

Common situations: issueId sourced from an external tracker (Jira/GitHub) that has not been synced into issueRepository; multi-tenant store isolation; stale bookmark/URL.

Related errors


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