ruvnet/ruflo · error

Cannot supersede: anchor "${oldId}" not found

Error message

Cannot supersede: anchor "${oldId}" not found

What it means

Thrown by TruthAnchorStore.supersede(oldId, params) when no anchor with the given ID exists in the store. Supersession works by embedding the old anchor's ID in the new anchor's supersedes array to form a verifiable chain, so the referenced anchor must already exist. Note that the store evicts expired anchors under capacity pressure (LRU), so an ID that once existed can disappear.

Source

Thrown at v3/@claude-flow/guidance/src/truth-anchors.ts:348

      }
    }

    return { valid, invalid };
  }

  /**
   * Create a new anchor that supersedes an existing one.
   *
   * The old anchor remains in the store (immutable) but the new
   * anchor's `supersedes` array includes the old anchor's ID.
   * This creates a verifiable supersession chain.
   *
   * Throws if the old anchor ID does not exist.
   */
  supersede(oldId: string, params: AnchorParams): TruthAnchor {
    const old = this.get(oldId);
    if (!old) {
      throw new Error(`Cannot supersede: anchor "${oldId}" not found`);
    }

    const supersedes = [...(params.supersedes ?? [])];
    if (!supersedes.includes(oldId)) {
      supersedes.push(oldId);
    }

    return this.anchor({
      ...params,
      supersedes,
    });
  }

  /**
   * Resolve a claim against an internal belief.
   *
   * Searches for active truth anchors whose claim matches the
   * provided claim text. If a matching truth anchor exists and

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Verify existence first: if (!store.get(oldId)) throw — use the exact id string returned by anchor creation
  2. Capture and reuse the id returned from const { id } = store.anchor(params) rather than reconstructing IDs by hand
  3. If anchors are being evicted, raise capacity in TruthAnchorConfig or import the historical anchors before superseding

Example fix

// before
store.supersede(oldAnchorId, params); // throws if ID unknown/evicted

// after
if (!store.get(oldAnchorId)) {
  throw new Error(`anchor ${oldAnchorId} missing; create or import it first`);
}
store.supersede(oldAnchorId, params);
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the anchor exists (and has not been evicted) before superseding
if (!store.get(oldId)) {
  throw new Error(`cannot supersede '${oldId}': not present in this store (evicted or foreign ID)`);
}
const next = store.supersede(oldId, params);

Type guard

function anchorExists(store: TruthAnchorStore): (id: string) => id is string & { __exists: never } {
  // simpler: just use the boolean below in conditionals
  return ((id: string) => store.get(id) !== undefined) as never;
}
// pragmatic check:
const exists = (id: string) => store.get(id) !== undefined;

Try / catch

try {
  return store.supersede(oldId, params);
} catch (e) {
  if (e instanceof Error && e.message.includes('not found')) {
    // recover: (re)create the base anchor, then supersede it
    const base = store.anchor(baseParams);
    return store.supersede(base.id, params);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling supersede with a typo'd or truncated ID; using an ID obtained from a different store instance (e.g. after a restart without re-importing); referencing an anchor that was LRU-evicted after capacity was exceeded; calling supersede before the original anchor() call completed.

Common situations: Persisting anchor IDs externally and replaying them against a fresh store; long-running stores where capacity eviction removed old anchors; string-vs-anchor-object confusion (passing an anchor object or its content hash instead of its id field).

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/807fbaf623ab5f13. Report an issue: GitHub.