ruvnet/ruflo · error · Error

project-local flywheel anchor required; create ${DEFAULT_PRO

Error message

project-local flywheel anchor required; create ${DEFAULT_PROJECT_ANCHOR_MANIFEST} or pass anchorPath + anchorHash

What it means

Thrown as the terminal fall-through of loadEffectiveFlywheelAnchor(): no explicit anchorPath/anchorHash pair was supplied, no manifest file exists at the default location (.claude/eval/flywheel-anchor.manifest.json) or the given manifestPath, AND the current project is not the Ruflo repository itself (nor has RUFLO_FLYWHEEL_ALLOW_BUILTIN_ANCHOR=1). This is the fail-closed design from issue #2840: foreign projects MUST supply their own pinned anchor rather than silently inheriting Ruflo's development-history benchmark, because evaluating against Ruflo's tasks makes the objective flat and indistinguishable from 'already optimal'.

Source

Thrown at v3/@claude-flow/cli/src/services/harness-project-anchor.ts:185

    const requested = existsSync(manifestRelative) ? manifestRelative : resolve(root, manifest.path);
    return toSelection(containedPath(root, requested), manifest.sha256);
  }

  if (isRufloRepository(root) || process.env.RUFLO_FLYWHEEL_ALLOW_BUILTIN_ANCHOR === '1') {
    const frozen = loadFrozenHumanEval();
    return {
      version: frozen.version,
      anchorRef: FROZEN_HUMAN_EVAL_HASH,
      source: 'ruflo-built-in',
      tasks: frozen.tasks.map((task) => ({
        id: task.id,
        input: { id: task.id, q: task.q },
        expected: task.labels,
      })),
    };
  }

  throw new Error(
    `project-local flywheel anchor required; create ${DEFAULT_PROJECT_ANCHOR_MANIFEST} or pass anchorPath + anchorHash`,
  );
}

View on GitHub (pinned to 6b01dc5a68)

Solutions

  1. Create .claude/eval/flywheel-anchor.manifest.json with the manifest schema, pointing at a tasks JSON and its pinned sha256 (see errors 388/389 for the shape).
  2. Alternatively, call loadEffectiveFlywheelAnchor with both anchorPath and anchorHash set explicitly.
  3. For local experimentation only, set RUFLO_FLYWHEEL_ALLOW_BUILTIN_ANCHOR=1 to opt into the frozen built-in anchor (do not use this for real benchmarking of foreign projects).

Example fix

// before — no manifest, no explicit anchor, in a non-Ruflo repo
loadEffectiveFlywheelAnchor(process.cwd())
// after — create .claude/eval/flywheel-anchor.manifest.json:
// { "schemaVersion":"ruflo.flywheel-anchor-manifest/v1",
//   "path":"tasks.json", "sha256":"sha256:<humanEvalHash of tasks.json>" }
// or pass both options:
loadEffectiveFlywheelAnchor(process.cwd(), {
  anchorPath: '.claude/eval/tasks.json',
  anchorHash: 'sha256:<hash>',
})
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync } from 'fs';
import { DEFAULT_PROJECT_ANCHOR_MANIFEST } from './harness-project-anchor.js';
function ensureAnchorAvailable(root: string, opts: { anchorPath?: string; anchorHash?: string; manifestPath?: string }) {
  const hasExplicit = !!opts.anchorPath && !!opts.anchorHash;
  const manifest = opts.manifestPath ?? `${root}/${DEFAULT_PROJECT_ANCHOR_MANIFEST}`;
  if (!hasExplicit && !existsSync(manifest) && process.env.RUFLO_FLYWHEEL_ALLOW_BUILTIN_ANCHOR !== '1') {
    throw new Error(`No anchor configured. Create ${manifest} (schema 'ruflo.flywheel-anchor-manifest/v1', path+sha256) or pass anchorPath+anchorHash.`);
  }
}

Try / catch

try {
  loadEffectiveFlywheelAnchor(root, opts);
} catch (e) {
  if (e instanceof Error && /project-local flywheel anchor required/.test(e.message)) {
    // onboard the repo: author a tasks JSON, compute its hash, write the manifest, then retry
  }
  throw e;
}

Prevention

When it happens

Trigger: Running the flywheel/harness in any repository other than ruflo/claude-flow without first creating a manifest at .claude/eval/flywheel-anchor.manifest.json, and without passing anchorPath+anchorHash to loadEffectiveFlywheelAnchor(). Also fires when manifestPath points to a non-existent custom location.

Common situations: First-time flywheel run in a downstream repo that hasn't been onboarded; CI running the harness in a fresh checkout before the manifest was committed; a monorepo where the manifest exists in a different package root than the one passed as projectRoot; a contributor who deleted the manifest thinking it was generated.

Related errors


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