{"record":{"id":"3a5028ce8516f3f7","repo":"ruvnet/ruflo","slug":"flywheel-anchor-manifest-requires-path-and-sha256","errorCode":null,"errorMessage":"flywheel anchor manifest requires path and sha256","messagePattern":"flywheel anchor manifest requires path and sha256","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/services/harness-project-anchor.ts","lineNumber":162,"sourceCode":"  if (!!options.anchorPath !== !!options.anchorHash) {\n    throw new Error('anchorPath and anchorHash must be supplied together');\n  }\n  if (options.anchorPath && options.anchorHash) {\n    return toSelection(containedPath(root, options.anchorPath), options.anchorHash);\n  }\n\n  const manifestCandidate = options.manifestPath ?? DEFAULT_PROJECT_ANCHOR_MANIFEST;\n  const manifestPath = isAbsolute(manifestCandidate)\n    ? manifestCandidate\n    : resolve(root, manifestCandidate);\n  if (existsSync(manifestPath)) {\n    const containedManifest = containedPath(root, manifestPath);\n    const manifest = JSON.parse(readFileSync(containedManifest, 'utf8')) as ProjectAnchorManifest;\n    if (manifest.schemaVersion !== PROJECT_ANCHOR_MANIFEST_SCHEMA) {\n      throw new Error(`unsupported flywheel anchor manifest schema: ${manifest.schemaVersion}`);\n    }\n    if (typeof manifest.path !== 'string' || typeof manifest.sha256 !== 'string') {\n      throw new Error('flywheel anchor manifest requires path and sha256');\n    }\n    // Manifest-relative paths are easier to relocate while remaining\n    // repository-contained; project-relative paths remain supported.\n    const manifestRelative = resolve(dirname(containedManifest), manifest.path);\n    const requested = existsSync(manifestRelative) ? manifestRelative : resolve(root, manifest.path);\n    return toSelection(containedPath(root, requested), manifest.sha256);\n  }\n\n  if (isRufloRepository(root) || process.env.RUFLO_FLYWHEEL_ALLOW_BUILTIN_ANCHOR === '1') {\n    const frozen = loadFrozenHumanEval();\n    return {\n      version: frozen.version,\n      anchorRef: FROZEN_HUMAN_EVAL_HASH,\n      source: 'ruflo-built-in',\n      tasks: frozen.tasks.map((task) => ({\n        id: task.id,\n        input: { id: task.id, q: task.q },\n        expected: task.labels,","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/ruvnet/ruflo/blob/6b01dc5a687b26b3e218f796de45ec51f8fa9e8c/v3/@claude-flow/cli/src/services/harness-project-anchor.ts#L144-L180","documentation":"Thrown after the manifest schema check passes, when manifest.path or manifest.sha256 is missing or not a string. Both fields are mandatory: path locates the tasks JSON (relative to the manifest or to the project root) and sha256 is the pinned hash that toSelection() will verify. A manifest with only one of the two is treated as malformed because the integrity pin would be incomplete.","triggerScenarios":"A manifest JSON where path or sha256 is absent, null, a number, or an empty string; a key typo like \"file\" instead of \"path\" or \"hash\" instead of \"sha256\"; a partially-written manifest from a crashed generator.","commonSituations":"Authoring the manifest by hand and omitting sha256 because the hash wasn't computed yet; renaming keys to friendlier names; a templating system that left one field as null when the value was unavailable.","solutions":["Ensure both \"path\" and \"sha256\" are present and are non-empty strings.","Compute the sha256 over the referenced tasks file (via humanEvalHash) and paste it in.","Validate the manifest shape with a JSON-schema or hand check before pointing the harness at it."],"exampleFix":"// before\n{ \"schemaVersion\": \"ruflo.flywheel-anchor-manifest/v1\", \"path\": \"tasks.json\" }\n// after\n{ \"schemaVersion\": \"ruflo.flywheel-anchor-manifest/v1\", \"path\": \"tasks.json\", \"sha256\": \"sha256:abc123...\" }","handlingStrategy":"validation","validationCode":"function assertManifestFields(path: string): void {\n  const m = JSON.parse(readFileSync(path, 'utf8'));\n  if (typeof m.path !== 'string' || typeof m.sha256 !== 'string') {\n    throw new Error('manifest requires string path and sha256');\n  }\n}","typeGuard":"function isCompleteManifest(m: unknown): m is { schemaVersion: string; path: string; sha256: string } {\n  return typeof m === 'object' && m !== null\n    && typeof (m as { path?: unknown }).path === 'string'\n    && typeof (m as { sha256?: unknown }).sha256 === 'string';\n}","tryCatchPattern":"try {\n  loadEffectiveFlywheelAnchor(root, opts);\n} catch (e) {\n  if (e instanceof Error && /manifest requires path and sha256/.test(e.message)) {\n    // add the missing string field(s) to the manifest, then retry\n  }\n  throw e;\n}","preventionTips":["Always pair path with a freshly-computed sha256 when writing the manifest.","Use the exact key names 'path' and 'sha256'.","Add a generator test asserting both fields are non-empty strings."],"tags":["flywheel-anchor","validation","manifest","configuration","json"],"backgroundTag":null,"analyzedSha":"6b01dc5a687b26b3e218f796de45ec51f8fa9e8c","analyzedAt":"2026-08-12T13:20:50.148Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}