ruvnet/ruflo · error

Amendment not found: ${amendmentId}

Error message

Amendment not found: ${amendmentId}

What it means

MetaGovernor.voteOnAmendment() looks up the live amendments map, which only holds amendments between proposeAmendment() and their terminal transition — both enactAmendment() and vetoAmendment() delete the entry and move it to amendmentHistory. 'Amendment not found' therefore means the ID was never proposed on this instance, was already enacted, was already vetoed, or came from another governor instance (all state is in-memory).

Source

Thrown at v3/@claude-flow/guidance/src/meta-governance.ts:391

    const amendment: Amendment = {
      id: randomUUID(),
      timestamp: now,
      status: 'proposed',
      votes: new Map(),
      ...proposal,
    };

    this.amendments.set(amendment.id, amendment);
    return amendment;
  }

  /**
   * Vote on an amendment
   */
  voteOnAmendment(amendmentId: string, voterId: string, approve: boolean): void {
    const amendment = this.amendments.get(amendmentId);
    if (!amendment) {
      throw new Error(`Amendment not found: ${amendmentId}`);
    }
    if (amendment.status !== 'proposed') {
      throw new Error(`Cannot vote on amendment with status: ${amendment.status}`);
    }

    amendment.votes.set(voterId, approve);
  }

  /**
   * Resolve an amendment (check if supermajority reached)
   */
  resolveAmendment(amendmentId: string): Amendment {
    const amendment = this.amendments.get(amendmentId);
    if (!amendment) {
      throw new Error(`Amendment not found: ${amendmentId}`);
    }
    if (amendment.status !== 'proposed') {
      throw new Error(`Amendment already resolved: ${amendment.status}`);

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Vote using the exact id returned by proposeAmendment() on the same governor instance, before resolve/enact/veto
  2. Pre-check governor.getPendingAmendments() to confirm the amendment is still live
  3. Consult getAmendmentHistory() to see whether it was already enacted or vetoed
  4. Catch the error and treat it as 'vote window closed' — the amendment already reached a terminal state

Example fix

// before
governor.voteOnAmendment(amendmentId, 'voter-1', true);
// after
const isLive = governor.getPendingAmendments().some(a => a.id === amendmentId);
if (!isLive) {
  logger.warn('Amendment no longer pending; vote dropped', { amendmentId });
} else {
  governor.voteOnAmendment(amendmentId, 'voter-1', true);
}
Defensive patterns

Strategy: validation

Validate before calling

const live = governor.getPendingAmendments().find(a => a.id === amendmentId);
if (!live) {
  const historical = governor.getAmendmentHistory().find(a => a.id === amendmentId);
  logger.warn('Amendment not votable', { amendmentId, terminal: historical?.status ?? 'unknown' });
  return;
}
governor.voteOnAmendment(amendmentId, voterId, approve);

Type guard

function isVotable(governor: MetaGovernor, id: string): boolean {
  return governor.getPendingAmendments().some(a => a.id === id); // status === 'proposed'
}

Try / catch

try {
  governor.voteOnAmendment(amendmentId, voterId, approve);
} catch (err) {
  if (err instanceof Error && err.message.startsWith('Amendment not found')) {
    return; // enacted/vetoed/restarted: vote window closed
  }
  throw err;
}

Prevention

When it happens

Trigger: Voting after the amendment was enacted or vetoed (both remove it from the map); passing a typo'd or foreign ID; voting on a new MetaGovernor after a process restart; using an id copied from getAmendmentHistory() instead of a live proposal.

Common situations: Multi-voter flows where enactment races a late vote; job replays after restart; mixing historical and live amendment IDs in logs.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/9b7fb5a3b2768a45. Report an issue: GitHub.