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 codeView on GitHub (pinned to 07edf82a04)
Solutions
- Convert each analysisPaths entry to a project-relative path before writing the input JSON: path.relative(projectRoot, absPath) with forward slashes.
- Reuse the exact `path` values from the `files` array of the same input (they are already project-relative and guaranteed to match).
- 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
- Always derive analysisPaths from the files inventory's `path` fields rather than from absolute filesystem paths.
- Normalize with path.relative(projectRoot, ...) and forward slashes before writing the input JSON.
- Unit-test input builders on both POSIX and Windows path shapes.
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
- Invalid input: analysisPaths entry escapes projectRoot: ${ra
- Invalid input: analysisPaths entry is not present in files:
AI-assisted analysis of Egonex-AI/Understand-Anything@07edf82a04 (2026-09-07).
Data as JSON: /api/errors/67e86b6b1b3be0ab.
Report an issue: GitHub.