Egonex-AI/Understand-Anything · error

Invalid input: analysisPaths entry must be project-relative:

Error message

Invalid input: analysisPaths entry must be project-relative: ${rawPath}

What it means

extract-import-map.mjs validates every entry of the optional `analysisPaths` input array through selectAnalysisFiles(). Each entry must be a project-relative path (e.g. "src/index.ts"), not an absolute one. The script throws this error when path.isAbsolute(rawPath) is true, because selective analysis is only defined over files already listed in the `files` inventory, which uses project-relative paths; absolute paths would bypass that contract and could point outside projectRoot.

Source

Thrown at understand-anything-plugin/skills/understand/extract-import-map.mjs:135

  const filesByPath = new Map();
  for (const file of files) {
    if (!file || typeof file.path !== 'string' || file.path.length === 0) {
      throw new Error('Invalid input: every files entry must contain a non-empty path');
    }
    filesByPath.set(toPosix(file.path), file);
  }

  const selected = [];
  const seen = new Set();
  for (const rawPath of analysisPaths) {
    if (typeof rawPath !== 'string' || rawPath.length === 0) {
      throw new Error('Invalid input: every analysisPaths entry must be a non-empty string');
    }
    // Use the host's path semantics here. On POSIX, backslashes and drive-like
    // prefixes are ordinary project-relative filename characters; on Windows,
    // path.isAbsolute also rejects drive-rooted and root-relative paths.
    if (isAbsolute(rawPath)) {
      throw new Error(`Invalid input: analysisPaths entry must be project-relative: ${rawPath}`);
    }
    const path = toPosix(rawPath);
    if (!path || path.split('/').some(part => part === '..')) {
      throw new Error(`Invalid input: analysisPaths entry escapes projectRoot: ${rawPath}`);
    }
    const file = filesByPath.get(path);
    if (!file) {
      throw new Error(`Invalid input: analysisPaths entry is not present in files: ${rawPath}`);
    }
    if (!seen.has(path)) {
      seen.add(path);
      selected.push(file);
    }
  }
  return selected;
}

// ECMAScript relational string comparison is lexicographic over UTF-16 code

View on GitHub (pinned to 07edf82a04)

Solutions

  1. Convert each analysisPaths entry to a project-relative path before writing the input JSON: path.relative(projectRoot, absPath) with forward slashes.
  2. Reuse the exact `path` values from the `files` array of the same input (they are already project-relative and guaranteed to match).
  3. On Windows, strip drive-letter/root prefixes or ensure entries like "src/index.ts" rather than "/src/index.ts" or "C:\\src\\index.ts".

Example fix

// before
const input = { projectRoot, files, analysisPaths: changedFiles.map(f => f.absolutePath) };
// after
const input = { projectRoot, files, analysisPaths: changedFiles.map(f => path.relative(projectRoot, f.absolutePath).split(path.sep).join('/')) };
Defensive patterns

Strategy: validation

Validate before calling

import { isAbsolute, relative, sep } from 'node:path';
function assertProjectRelative(p, projectRoot) {
  if (typeof p !== 'string' || p.length === 0) throw new Error('empty path');
  if (isAbsolute(p)) throw new Error(`must be project-relative: ${p}`);
  const rel = relative(projectRoot, p);
  if (rel.startsWith('..')) throw new Error(`escapes projectRoot: ${p}`);
}

Type guard

const isProjectRelative = (p) => typeof p === 'string' && p.length > 0 && !isAbsolute(p);

Try / catch

try {
  await runExtractor(input);
} catch (err) {
  if (String(err.message).includes('analysisPaths entry must be project-relative')) {
    input.analysisPaths = input.analysisPaths.map(p => relative(projectRoot, p).split(sep).join('/'));
    await runExtractor(input);
  } else throw err;
}

Prevention

When it happens

Trigger: Calling the script with input JSON whose analysisPaths contains an absolute path such as "/home/user/project/src/index.ts" or "C:\\proj\\src\\index.ts" (on Windows, path.isAbsolute also rejects root-relative paths like "/src/index.ts" and drive-rooted ones like "C:src"). Any tool or agent that passes filesystem-absolute paths instead of the project-relative paths used in the `files` array triggers it.

Common situations: An incremental-run caller builds analysisPaths from its own CLI arguments or editor-absolute file paths instead of from scan-result inventory paths; a Windows developer passes drive-lettered paths; a script joins projectRoot into the entry before writing the input JSON (e.g. path.join(projectRoot, relPath)) making it absolute.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of Egonex-AI/Understand-Anything@07edf82a04 (2026-09-07). Data as JSON: /api/errors/67e86b6b1b3be0ab. Report an issue: GitHub.