ruvnet/ruflo · error · Error
localCompute: no adapter for graphId=${input.graphId}
Error message
localCompute: no adapter for graphId=${input.graphId} What it means
validateConfigPath() only lets through paths ending in .json, .config.json, .config.js, or .config.ts (the longer entries are redundant since plain .json already matches). Any other extension — or a wrong-case extension like .JSON — fails the case-sensitive endsWith() checks. This is a whitelist so that the config tools cannot be repurposed to read or overwrite arbitrary file types.
Source
Thrown at plugins/ruflo-graph-intelligence/src/application/federation-client.ts:118
}
// No usable response
return {
origin: 'local-fallback',
result: await this.localCompute(input),
fallbackReason: 'no usable response from peer',
};
}
private async localCompute(input: {
graphId: string;
nodeId: string;
alpha?: number;
epsilon?: number;
seedNodes?: string[];
}): Promise<PageRankResult> {
const adapter = getRegistry().get(input.graphId);
if (!adapter) {
throw new Error(`localCompute: no adapter for graphId=${input.graphId}`);
}
const matrix = await adapter.exportAsSparseMatrix();
return runPageRank(matrix, {
graphId: input.graphId,
nodeId: input.nodeId,
alpha: input.alpha ?? 0.85,
epsilon: input.epsilon ?? 1e-3,
seedNodes: input.seedNodes ?? [],
maxComplexityClass: 'polynomial',
coherenceThreshold: 0,
});
}
}
/**
* Helper: an in-process transport stitching a client to a server. Useful for
* testing the Phase 8 round-trip without spinning up real ADR-104 wiring.
*/View on GitHub (pinned to fa13ee4ad6)
Solutions
- Use a .json config file — that is the format handleSaveConfig writes with JSON.stringify anyway
- Convert your YAML/TOML config to JSON (e.g. with js-yaml's safeLoad + JSON.stringify) and save it as claude-flow.config.json
- Check the exact extension casing of the file on disk and pass it verbatim (lowercase .json)
- For .config.js/.config.ts files, confirm the full suffix matches, e.g. "claude-flow.config.ts" not "claude-flow.ts"
Example fix
// before
await client.callTool('config_load', { path: 'config/claude-flow.yaml' }); // throws [1122]
// after
import fs from 'fs';
import yaml from 'js-yaml';
const cfg = yaml.load(fs.readFileSync('config/claude-flow.yaml', 'utf-8'));
fs.writeFileSync('config/claude-flow.config.json', JSON.stringify(cfg, null, 2));
await client.callTool('config_load', { path: 'config/claude-flow.config.json' }); Defensive patterns
Strategy: validation
Validate before calling
const ALLOWED = ['.json', '.config.json', '.config.js', '.config.ts'];
function hasAllowedConfigExt(p: string): boolean {
const lower = p.toLowerCase();
return ALLOWED.some(ext => lower.endsWith(ext));
} Prevention
- Keep claude-flow config as .json; convert YAML/TOML at build time, not tool-call time
- Assert hasAllowedConfigExt(path) before every config tool call in a shared wrapper
- Watch extension casing — the server's endsWith check is case-sensitive
When it happens
Trigger: path="claude-flow.config.yaml" or "config.yml"; path="settings.toml"; a case mismatch like "CONFIG.JSON" (endsWith is case-sensitive); a path with no extension at all, e.g. "config/production".
Common situations: Teams whose existing config lives in YAML/TOML trying to point claude-flow at it; tools that emit uppercase extensions; users assuming any text file can be loaded as config.
Related errors
- Key exceeds maximum nesting depth of ${MAX_NESTING_DEPTH}
- Dangerous key segment rejected: ${part}
- unknown game "${key}". Known: ${Object.keys(GAMES).join(', '
- unknown strategy "${name}". Available: ${roster.map((r) => r
- signBacktestArtifact: privateKey must be 32 bytes (got ${pri
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/ccf53b6d9a2e486f.
Report an issue: GitHub.