ruvnet/ruflo · error · Error

localSingleEntryPageRank: sourceIndex ${src} out of range [0

Error message

localSingleEntryPageRank: sourceIndex ${src} out of range [0, ${n})

What it means

This is the second, defense-in-depth check in getSessionPath(): after the strict charset validation passes, it path.resolve()s both the assembled session file path and the session directory and requires the file path to start with the directory plus a path separator. With the regex already forbidding '/', '\', and '..', it should be unreachable through the sessionId alone; in practice it fires when the directory itself resolves somewhere unexpected, e.g. process.cwd() contains a symlink so resolvedDir differs from the joined prefix.

Source

Thrown at plugins/ruflo-neural-trader/src/signed-attribution.ts:219

 * The math: standard personalized PageRank with the personalization vector
 * concentrated entirely on the source node. Forward-push semantics in the
 * limit, plain power iteration on a small in-memory graph in practice.
 * Seeded so that two runs with the same graph + same seed return byte-
 * identical ordering (asserted by the Phase 6 smoke's reproducibility
 * check).
 */
export function localSingleEntryPageRank(
  graph: AttributionGraph,
  opts: PageRankOptions,
): PageRankResult {
  const n = graph.nodes.length;
  if (n === 0) return { scores: [], iterations: 0 };
  const damping = opts.damping ?? 0.85;
  const maxIter = opts.maxIterations ?? 100;
  const tol = opts.tolerance ?? 1e-8;
  const src = opts.sourceIndex;
  if (src < 0 || src >= n) {
    throw new Error(
      `localSingleEntryPageRank: sourceIndex ${src} out of range [0, ${n})`,
    );
  }

  // Personalization vector concentrated on src.
  const personalization = new Float64Array(n);
  personalization[src] = 1;

  // Initialize: seeded deterministic noise then re-normalize so the start
  // vector still sums to 1. The seed controls the initialization only —
  // PageRank converges to the same stationary distribution regardless, but
  // the iteration *order* and the path through the state space depend on
  // the seed when ties are present. This is what the smoke asserts.
  let rng = mulberry32(opts.seed);
  let r = new Float64Array(n);
  let sum = 0;
  for (let i = 0; i < n; i++) {
    // Small positive noise so we don't divide by zero on degenerate graphs.

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Start the MCP server from the real (non-symlinked) physical path: cd $(readlink -f .) before launching
  2. Replace the .claude-flow/sessions symlink with a real directory (or bind mount)
  3. Regenerate sessions under the corrected directory so old and new paths agree
  4. If it persists, log path.resolve(cwd) inside getSessionPath to see which prefix mismatch triggers it

Example fix

# before: server started via a symlinked path
ln -s /srv/releases/2026-08-18 /srv/current
(cd /srv/current && start-mcp-server)  # session ops may throw [1126]

# after: launch from the physical path
cd /srv/releases/2026-08-18 && start-mcp-server
Defensive patterns

Strategy: validation

Validate before calling

import { resolve, join } from 'path';
function sessionPathIsContained(sessionId: string, cwd = process.cwd()): boolean {
  const dir = resolve(cwd, '.claude-flow/sessions');
  const file = resolve(dir, `${sessionId}.json`);
  return file.startsWith(dir + sep);
}

Prevention

When it happens

Trigger: MCP server started in a symlinked directory (e.g. /tmp -> /private/tmp on macOS) where path.resolve(sessionPath) and path.resolve(sessionDir) normalize through different symlink chains; DEFAULT_SESSION_DIR (".claude-flow/sessions") being itself a symlink pointing elsewhere; exotic cwd states (deleted working directory).

Common situations: macOS /tmp symlink issues when running the server from a temp checkout; deployment layouts where the project dir is a symlink (current -> releases/2026-08-18) and different code paths resolve it differently.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/0e54f4e44c0d3773. Report an issue: GitHub.