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

  1. Pass non-empty absolute path strings for both parameters
  2. Normalize empty strings to undefined before calling so the default applies
  3. 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

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


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