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
- Pass the exact directory recorded at server startup; print and reuse its realpath
- Resolve to the canonical path first: node -e "console.log(require('node:fs').realpathSync(process.cwd()))"
- 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
- Record the realpath of the checkout at server startup and reuse exactly that value for every call
- Beware macOS /tmp -> /private/tmp and other symlinked prefixes; resolve before comparing
- Pass the checkout root, not a subdirectory, as repo
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
- Refusing CLI access: repository marker escapes the trusted r
- Refusing CLI access: README marker is not a regular file
- Refusing CLI access: trusted root is not a directory
- Refusing CLI access: Homecore repository markers are missing
- Refusing CLI access: README does not identify a RuView check
AI-assisted analysis of ruvnet/RuView@4685618388 (2026-08-16).
Data as JSON: /api/errors/dc961f8b337093c5.
Report an issue: GitHub.