{"record":{"id":"e9e2473168a1888a","repo":"ruvnet/ruflo","slug":"unsupported-flywheel-anchor-schema-parsed-schem","errorCode":null,"errorMessage":"unsupported flywheel anchor schema: ${parsed.schemaVersion}","messagePattern":"unsupported flywheel anchor schema: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/services/harness-project-anchor.ts","lineNumber":81,"sourceCode":"  if (lexical === '..' || lexical.startsWith(`..${sep}`) || isAbsolute(lexical)) {\n    throw new Error('flywheel anchor path must stay inside project root');\n  }\n  const actual = realpathSync(absolute);\n  const physical = relative(root, actual);\n  if (physical === '..' || physical.startsWith(`..${sep}`) || isAbsolute(physical)) {\n    throw new Error('flywheel anchor symlink escapes project root');\n  }\n  return actual;\n}\n\nfunction parseTasks(path: string): { version: string; tasks: HumanEvalTask[] } {\n  const parsed = JSON.parse(readFileSync(path, 'utf8')) as {\n    schemaVersion?: string;\n    version?: string;\n    tasks?: HumanEvalTask[];\n  };\n  if (parsed.schemaVersion && parsed.schemaVersion !== PROJECT_ANCHOR_SCHEMA) {\n    throw new Error(`unsupported flywheel anchor schema: ${parsed.schemaVersion}`);\n  }\n  if (!Array.isArray(parsed.tasks) || parsed.tasks.length < 4) {\n    throw new Error('project flywheel anchor requires at least 4 labelled tasks');\n  }\n  const ids = new Set<string>();\n  for (const [index, task] of parsed.tasks.entries()) {\n    if (!task || typeof task.id !== 'string' || !/^[A-Za-z0-9._-]{1,128}$/.test(task.id)) {\n      throw new Error(`invalid anchor task id at index ${index}`);\n    }\n    if (ids.has(task.id)) throw new Error(`duplicate anchor task id: ${task.id}`);\n    ids.add(task.id);\n    if (typeof task.q !== 'string' || task.q.trim().length === 0) {\n      throw new Error(`anchor task ${task.id} has no query`);\n    }\n    if (!Array.isArray(task.labels) || task.labels.length === 0 || task.labels.some((label) => typeof label !== 'string' || !label.trim())) {\n      throw new Error(`anchor task ${task.id} requires non-empty string labels`);\n    }\n  }","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/ruvnet/ruflo/blob/6b01dc5a687b26b3e218f796de45ec51f8fa9e8c/v3/@claude-flow/cli/src/services/harness-project-anchor.ts#L63-L99","documentation":"Thrown by parseTasks() in harness-project-anchor.ts when a project-local flywheel anchor JSON file declares a schemaVersion that is not 'ruflo.flywheel-anchor/v1' (the value of PROJECT_ANCHOR_SCHEMA). The schemaVersion field is optional, but when present it must match exactly; this guards against silently consuming an anchor written for a future or incompatible schema. Ruflo pins anchors per-repository so foreign projects are evaluated against their own labelled tasks, not Ruflo's built-in benchmark.","triggerScenarios":"Loading an anchor file via loadEffectiveFlywheelAnchor() (either through an explicit anchorPath, or indirectly via the .claude/eval/flywheel-anchor.manifest.json) where the JSON contains a schemaVersion like 'ruflo.flywheel-anchor/v2', 'v1', or any typo. The field is optional, so a JSON without schemaVersion passes this check.","commonSituations":"Hand-editing an anchor file and mistyping the schema string; upgrading claude-flow/ruflo to a version whose schema constant changed while keeping an old anchor file that used a custom/placeholder value; copying an anchor template from documentation that used a non-literal placeholder; AI-generated anchor files inventing a plausible-looking schemaVersion.","solutions":["Set schemaVersion to exactly \"ruflo.flywheel-anchor/v1\" in the anchor JSON, or delete the field entirely (it is optional).","Re-generate the anchor file with the project's official scaffolding/CLI command so the schema constant is written verbatim.","If you intentionally authored a v2-format anchor, downgrade the payload to the v1 shape until the library supports it."],"exampleFix":"// before (anchor.json)\n{ \"schemaVersion\": \"ruflo.flywheel-anchor/v2\", \"tasks\": [...] }\n// after\n{ \"schemaVersion\": \"ruflo.flywheel-anchor/v1\", \"tasks\": [...] }\n// or simply omit the field\n{ \"version\": \"project-anchor-v1\", \"tasks\": [...] }","handlingStrategy":"validation","validationCode":"import { PROJECT_ANCHOR_SCHEMA } from './harness-project-anchor.js';\nimport { readFileSync } from 'fs';\nfunction assertAnchorSchema(path: string): void {\n  const parsed = JSON.parse(readFileSync(path, 'utf8'));\n  if (parsed.schemaVersion !== undefined && parsed.schemaVersion !== PROJECT_ANCHOR_SCHEMA) {\n    throw new Error(`anchor schema ${parsed.schemaVersion} != ${PROJECT_ANCHOR_SCHEMA}; fix or remove the field`);\n  }\n}","typeGuard":"function hasValidAnchorSchema(parsed: unknown): boolean {\n  if (typeof parsed !== 'object' || parsed === null) return false;\n  const sv = (parsed as { schemaVersion?: unknown }).schemaVersion;\n  return sv === undefined || sv === 'ruflo.flywheel-anchor/v1';\n}","tryCatchPattern":"try {\n  loadEffectiveFlywheelAnchor(root, { anchorPath, anchorHash });\n} catch (e) {\n  if (e instanceof Error && /unsupported flywheel anchor schema/.test(e.message)) {\n    // fix the schemaVersion field, then retry\n  }\n  throw e;\n}","preventionTips":["Generate anchor files with the official scaffolding so PROJECT_ANCHOR_SCHEMA is written verbatim.","Treat schemaVersion as opaque — never hand-type it.","Add a JSON-schema assertion in CI that validates anchor files before commit."],"tags":["flywheel-anchor","schema-validation","configuration","json"],"backgroundTag":null,"analyzedSha":"6b01dc5a687b26b3e218f796de45ec51f8fa9e8c","analyzedAt":"2026-08-12T13:20:50.148Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}