ruvnet/RuView · error · TypeError
repoRoot and trustedRoot are required
Error message
repoRoot and trustedRoot are required
What it means
assertTrustedHomecoreRepo() requires both repoRoot and trustedRoot to be non-empty. trustedRoot defaults to repoRoot, but explicitly passing '' or null in the options object overrides that default, so both parameters end up checked and this TypeError is thrown.
Source
Thrown at harness/homecore/src/repo-trust.js:64
export function looksLikeHomecoreRepo(path) {
if (!path || !existsSync(path)) return false;
return REQUIRED_MARKERS.every((marker) => existsSync(join(path, marker)));
}
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 non-empty absolute path strings for both parameters
- Normalize empty strings to undefined before calling so the default applies
- Validate CLI/env input before forwarding it to this function
Example fix
// before
assertTrustedHomecoreRepo(args.repo, { trustedRoot: env.HOMECORE_TRUSTED_ROOT ?? '' });
// after
const trusted = env.HOMECORE_TRUSTED_ROOT || args.repo;
assertTrustedHomecoreRepo(args.repo, { trustedRoot: trusted }); Defensive patterns
Strategy: type-guard
Validate before calling
const hasTrustRoots = (repoRoot, opts = {}) =>
Boolean(repoRoot) && Boolean(opts.trustedRoot ?? repoRoot);
if (!hasTrustRoots(args.repo, opts)) throw new TypeError('repoRoot and trustedRoot are required'); Type guard
/** @param {unknown} v @returns {v is string} */
function isNonEmptyPath(v) {
return typeof v === 'string' && v.trim().length > 0;
} Prevention
- Convert empty-string env/CLI values to undefined before passing them as trustedRoot so the default applies
- Resolve paths once at startup and pass the resolved values everywhere
- Validate required path arguments at the CLI boundary, not deep in trust verification
When it happens
Trigger: assertTrustedHomecoreRepo(''), assertTrustedHomecoreRepo(null), or assertTrustedHomecoreRepo(root, {trustedRoot: ''}) — typically an unvalidated --repo flag or an env variable that resolves to an empty string.
Common situations: Env-based config like process.env.HOMECORE_TRUSTED_ROOT ?? '' normalizing unset to empty string, CLI wrappers forwarding missing arguments verbatim.
Related errors
- command must be a non-empty string
- Unsupported verification profile: ${profile}
- args must be an array of strings
- Refusing CLI access: repository marker escapes the trusted r
- Refusing CLI access: README marker is not a regular file
AI-assisted analysis of ruvnet/RuView@4685618388 (2026-08-16).
Data as JSON: /api/errors/b506412ca605144e.
Report an issue: GitHub.