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.
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
- A trusted RuView checkout is required; pass repo.
- args must be an array of strings
- Circle requires 3 values: center_x,center_y,radius
AI-assisted analysis of ruvnet/RuView@4685618388 (2026-08-16).
Data as JSON: /api/errors/b506412ca605144e.
Report an issue: GitHub.
Appendix: 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)