ruvnet/ruflo · error · Error
Manifest not found
Error message
Manifest not found: ${localPath} What it means
loadLocalWitness() throws when the --manifest path passed to `ruflo verify` does not exist on disk. The local path is the offline/air-gapped alternative to fetching the manifest from GitHub, and this guard reports the missing file before any parsing or signature verification begins.
Solutions
- Check the path spelling and use an absolute path to rule out cwd issues
- ls the file from the exact directory the CLI runs in
- Download or copy the manifest first (e.g. curl -fsSL -o verification.md.json <url>) then re-run verify --manifest
Example fix
# before ruflo verify --manifest verif.json # after curl -fsSL -o /abs/path/verification.md.json https://raw.githubusercontent.com/ruvnet/ruflo/main/verification.md.json ruflo verify --manifest /abs/path/verification.md.json
Defensive patterns
Strategy: validation
Validate before calling
import { existsSync, resolve } from 'node:fs';
const manifest = resolve(manifestPath);
if (!existsSync(manifest)) {
throw new Error(`manifest missing at ${manifest} — download it before running verify`);
}
await runVerify({ manifest }); Prevention
- Use absolute paths for --manifest so cwd changes cannot break resolution
- Make manifest download a separate, checked step in CI before verify runs
- Verify the filename exactly — verification.md.json, not verification.json or verif.md.json
When it happens
Trigger: Running `ruflo verify --manifest ./verification.md.json` when the file was never downloaded, the path has a typo, or a relative path was resolved against a different working directory.
Common situations: Air-gapped verification where the download step was skipped; scripts running from a different cwd than expected; the manifest saved under a slightly different filename.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Failed to fetch manifest from
- approval issuance requires an authenticated human identity…
- File not found
- flywheel anchor manifest requires path and sha256
- Invalid container name
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/35556c7626a1d379.
Report an issue: GitHub.
Appendix: source
Thrown at v3/@claude-flow/cli/src/commands/verify.ts:70
};
}
const DEFAULT_MANIFEST_URL = 'https://raw.githubusercontent.com/ruvnet/ruflo/{branch}/verification.md.json';
async function fetchWitness(branch: string): Promise<Witness> {
const url = DEFAULT_MANIFEST_URL.replace('{branch}', branch);
// audit_1776853149979: bare fetch had no timeout — a hung GitHub CDN would
// pin the verify command indefinitely. 30s is generous for a sub-MB JSON.
const res = await fetch(url, { signal: AbortSignal.timeout(30000) });
if (!res.ok) {
throw new Error(`Failed to fetch manifest from ${url}: ${res.status} ${res.statusText}`);
}
return await res.json() as Witness;
}
function loadLocalWitness(localPath: string): Witness {
if (!existsSync(localPath)) {
throw new Error(`Manifest not found: ${localPath}`);
}
return JSON.parse(readFileSync(localPath, 'utf-8')) as Witness;
}
/**
* Locate the user's installed package root.
*
* The witness manifest paths are repo-relative (e.g.
* "v3/@claude-flow/cli/dist/src/mcp-tools/hooks-tools.js"). For
* end users, only the dist/ subtree ships in node_modules. We map
* the repo path → the installed equivalent by stripping the
* "v3/@claude-flow/<pkg>/" prefix and looking up node_modules/<pkg>/.
*/
function repoPathToInstalledPath(repoPath: string): string | null {
// Match v3/@claude-flow/<pkg>/<rest>
const match = repoPath.match(/^v3\/(@claude-flow\/[^/]+)\/(.+)$/);
if (match) {
const pkg = match[1];View on GitHub (pinned to fa13ee4ad6)