ruvnet/ruflo · error · Error
unsupported flywheel anchor manifest schema: ${manifest.sche
Error message
unsupported flywheel anchor manifest schema: ${manifest.schemaVersion} What it means
Thrown when the manifest file (default .claude/eval/flywheel-anchor.manifest.json) exists and parses as JSON, but its schemaVersion field does not equal 'ruflo.flywheel-anchor-manifest/v1' (PROJECT_ANCHOR_MANIFEST_SCHEMA). Note this check is strict equality (no optionality) — unlike the task anchor's optional schemaVersion, the manifest REQUIRES the exact schema string. The manifest is the small pointer file that pins a path+sha256 to a tasks JSON.
Source
Thrown at v3/@claude-flow/cli/src/services/harness-project-anchor.ts:159
options: LoadFlywheelAnchorOptions = {},
): FlywheelAnchorSelection {
const root = resolve(projectRoot);
if (!!options.anchorPath !== !!options.anchorHash) {
throw new Error('anchorPath and anchorHash must be supplied together');
}
if (options.anchorPath && options.anchorHash) {
return toSelection(containedPath(root, options.anchorPath), options.anchorHash);
}
const manifestCandidate = options.manifestPath ?? DEFAULT_PROJECT_ANCHOR_MANIFEST;
const manifestPath = isAbsolute(manifestCandidate)
? manifestCandidate
: resolve(root, manifestCandidate);
if (existsSync(manifestPath)) {
const containedManifest = containedPath(root, manifestPath);
const manifest = JSON.parse(readFileSync(containedManifest, 'utf8')) as ProjectAnchorManifest;
if (manifest.schemaVersion !== PROJECT_ANCHOR_MANIFEST_SCHEMA) {
throw new Error(`unsupported flywheel anchor manifest schema: ${manifest.schemaVersion}`);
}
if (typeof manifest.path !== 'string' || typeof manifest.sha256 !== 'string') {
throw new Error('flywheel anchor manifest requires path and sha256');
}
// Manifest-relative paths are easier to relocate while remaining
// repository-contained; project-relative paths remain supported.
const manifestRelative = resolve(dirname(containedManifest), manifest.path);
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) => ({View on GitHub (pinned to 6b01dc5a68)
Solutions
- Set the manifest's schemaVersion to exactly "ruflo.flywheel-anchor-manifest/v1".
- Double-check you are editing the MANIFEST file (.claude/eval/flywheel-anchor.manifest.json), not the TASKS file it points at — they use different schema constants.
- Re-generate the manifest via the project scaffolding so the constant is written verbatim.
Example fix
// before — .claude/eval/flywheel-anchor.manifest.json
{ "schemaVersion": "ruflo.flywheel-anchor/v1", "path": "tasks.json", "sha256": "sha256:..." }
// after — use the MANIFEST schema constant
{ "schemaVersion": "ruflo.flywheel-anchor-manifest/v1", "path": "tasks.json", "sha256": "sha256:..." } Defensive patterns
Strategy: validation
Validate before calling
import { PROJECT_ANCHOR_MANIFEST_SCHEMA } from './harness-project-anchor.js';
import { readFileSync } from 'fs';
function assertManifestSchema(path: string): void {
const m = JSON.parse(readFileSync(path, 'utf8'));
if (m.schemaVersion !== PROJECT_ANCHOR_MANIFEST_SCHEMA) {
throw new Error(`manifest schema ${m.schemaVersion} != ${PROJECT_ANCHOR_MANIFEST_SCHEMA}`);
}
} Type guard
function hasValidManifestSchema(manifest: unknown): boolean {
return typeof manifest === 'object' && manifest !== null
&& (manifest as { schemaVersion?: unknown }).schemaVersion === 'ruflo.flywheel-anchor-manifest/v1';
} Try / catch
try {
loadEffectiveFlywheelAnchor(root, opts);
} catch (e) {
if (e instanceof Error && /unsupported flywheel anchor manifest schema/.test(e.message)) {
// set manifest.schemaVersion to 'ruflo.flywheel-anchor-manifest/v1' (NOT the task schema)
}
throw e;
} Prevention
- Distinguish the MANIFEST schema constant from the TASK schema constant — they differ.
- Generate the manifest with the official scaffolding.
- Validate the manifest in CI with a JSON-schema.
When it happens
Trigger: A manifest file is present but its schemaVersion is missing, misspelled, or from a different version (e.g. 'v2', 'ruflo.flywheel-anchor/v1' which is the TASK schema not the MANIFEST schema). A common confusion is putting the task-anchor schema constant into the manifest file.
Common situations: Hand-authoring a manifest and copying the wrong schema string (the task schema instead of the manifest schema); a doc example that used a placeholder; upgrading the library when the manifest schema constant changed.
Related errors
- unsupported flywheel anchor schema: ${parsed.schemaVersion}
- flywheel anchor manifest requires path and sha256
- project flywheel anchor requires at least 4 labelled tasks
- anchor task ${task.id} has no query
- project-local flywheel anchor required; create ${DEFAULT_PRO
AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12).
Data as JSON: /api/errors/0619f3e74d31408a.
Report an issue: GitHub.