ruvnet/RuView · error · Error

Refusing CLI access: repository does not match the configure

Error message

Refusing CLI access: repository does not match the configured trusted root

What it means

The trust check realpaths both repoRoot and trustedRoot and requires them to be the exact same directory: isWithin(trustAnchor, root) alone would tolerate subdirectories, but the additional 'root !== trustAnchor' comparison enforces equality. Any mismatch — a nested directory, a different checkout, or a path that resolves differently after symlink resolution — throws this security error.

Source

Thrown at harness/homecore/src/repo-trust.js:68

export function findHomecoreRepo(start = process.cwd()) {
  let current = resolve(start);
  const root = parse(current).root;
  while (true) {
    if (looksLikeHomecoreRepo(current)) return realpathSync(current);
    if (current === root) return null;
    const parent = dirname(current);
    if (parent === current) return null;
    current = parent;
  }
}

export function assertTrustedHomecoreRepo(repoRoot, { trustedRoot = repoRoot } = {}) {
  if (!repoRoot || !trustedRoot) throw new TypeError('repoRoot and trustedRoot are required');
  const root = realpathSync(repoRoot);
  const trustAnchor = realpathSync(trustedRoot);
  if (!isWithin(trustAnchor, root) || root !== trustAnchor) {
    throw new Error('Refusing CLI access: repository does not match the configured trusted root');
  }
  if (!statSync(root).isDirectory()) {
    throw new Error('Refusing CLI access: trusted root is not a directory');
  }
  const missing = REQUIRED_MARKERS.filter((marker) => !existsSync(join(root, marker)));
  if (missing.length) {
    throw new Error(`Refusing CLI access: Homecore repository markers are missing (${missing.join(', ')})`);
  }
  const readme = readContainedPrefix(root, join(root, 'README.md'), 131_072);
  if (!/\b(?:RuView|wifi[- ]densepose)\b/i.test(readme)) {
    throw new Error('Refusing CLI access: README does not identify a RuView checkout');
  }
  return root;
}

View on GitHub (pinned to 4685618388)

Solutions

  1. Pass the exact directory recorded at server startup; print and reuse its realpath
  2. Resolve to the canonical path first: node -e "console.log(require('node:fs').realpathSync(process.cwd()))"
  3. Point --repo at the checkout root, never at a subdirectory

Example fix

# before
$ cd /tmp/ruview-link && homecore verify --repo /tmp/ruview-link
# /tmp/ruview-link symlinks to /private/tmp/... so realpath differs from the trusted root

# after
$ cd "$(pwd -P)" && homecore verify --repo "$(pwd -P)"
Defensive patterns

Strategy: validation

Validate before calling

import { realpathSync } from 'node:fs';
function sameRealDir(a, b) {
  try {
    return realpathSync(a) === realpathSync(b);
  } catch {
    return false;
  }
}
// use: if (!sameRealDir(args.repo, trustedRoot)) throw new Error('repo must equal the configured trusted root');

Prevention

When it happens

Trigger: Passing a subdirectory such as --repo checkout/v2, a symlinked path whose realpath differs from the configured trusted root (e.g. /tmp vs /private/tmp on macOS), or an MCP server whose startup trustedRoot differs from the repo argument of a later tool call.

Common situations: macOS symlinked temp directories, worktrees and symlinked clones, CI checking out to a different path than where the MCP server started, stale trusted-root configuration after moving the repo.

Related errors


AI-assisted analysis of ruvnet/RuView@4685618388 (2026-08-16). Data as JSON: /api/errors/dc961f8b337093c5. Report an issue: GitHub.