ruvnet/RuView · error · Error
Refusing CLI access: repository marker escapes the trusted r
Error message
Refusing CLI access: repository marker escapes the trusted root
What it means
Homecore's repo-trust module realpaths the README.md marker and verifies the resolved path stays inside the trusted root before reading it. If README.md is a symlink whose target resolves outside the root, this security error aborts CLI access, preventing the trust check from reading arbitrary files outside the checkout.
Source
Thrown at harness/homecore/src/repo-trust.js:30
const REQUIRED_MARKERS = Object.freeze([
'.git',
'README.md',
'v2/Cargo.toml',
'v2/crates/homecore/Cargo.toml',
'v2/crates/homecore-server/Cargo.toml',
'docs/adr/ADR-126-ruview-native-ha-port-master.md',
]);
function isWithin(parent, child) {
const rel = relative(parent, child);
return rel === '' || (!rel.startsWith('..') && !isAbsolute(rel));
}
function readContainedPrefix(root, path, maxBytes) {
const real = realpathSync(path);
if (!isWithin(root, real)) {
throw new Error('Refusing CLI access: repository marker escapes the trusted root');
}
const stat = statSync(real);
if (!stat.isFile()) {
throw new Error('Refusing CLI access: README marker is not a regular file');
}
const buffer = Buffer.alloc(Math.min(stat.size, maxBytes));
const descriptor = openSync(real, 'r');
try {
const bytes = readSync(descriptor, buffer, 0, buffer.length, 0);
return buffer.subarray(0, bytes).toString('utf8');
} finally {
closeSync(descriptor);
}
}
export function looksLikeHomecoreRepo(path) {
if (!path || !existsSync(path)) return false;
return REQUIRED_MARKERS.every((marker) => existsSync(join(path, marker)));View on GitHub (pinned to 4685618388)
Solutions
- Replace the README.md symlink with a real file inside the repository (copy the content in)
- If linking is required, link to a target still inside the checkout and re-run
- Confirm where it resolves: readlink -f README.md
Example fix
# before README.md -> /home/me/shared/README.md (symlink escaping the repo) # after $ rm README.md && cp /home/me/shared/README.md ./README.md (regular file inside the repo)
Defensive patterns
Strategy: validation
Validate before calling
import { realpathSync } from 'node:fs';
import { isAbsolute, join, relative } from 'node:path';
function readmeStaysInRoot(root) {
try {
const realRoot = realpathSync(root);
const real = realpathSync(join(root, 'README.md'));
const rel = relative(realRoot, real);
return rel === '' || (!rel.startsWith('..') && !isAbsolute(rel));
} catch {
return false;
}
} Prevention
- Keep README.md a regular file committed inside the repository — never a symlink outside it
- Audit checkouts for marker symlinks before running trust-gated CLIs: find . -maxdepth 1 -type l
- Treat this error as a security stop: fix the filesystem, do not catch and continue
When it happens
Trigger: README.md in the checkout root is a symlink to a file outside the repository (shared docs folder, home directory, another checkout). readContainedPrefix realpaths it, isWithin(root, real) fails, and assertTrustedHomecoreRepo throws during trust verification.
Common situations: Repos linking README.md to an absolute external path, dotfile-managed checkouts, monorepos sharing a README by symlink, test fixtures built with symlinks.
Related errors
- Refusing CLI access: repository does not match the configure
- 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/55fc6c77e6f2f261.
Report an issue: GitHub.