abhigyanpatwari/GitNexus · warning
[node] workspace-root scan of
Error message
[node] workspace-root scan of ${repoRoot} hit the ${WORKSPACE_ROOT_SCAN_MAX_DIRS}-directory cap; nested workspace roots below it were not considered What it means
This is a logged warning (not a thrown error) emitted during workspace-root discovery. GitNexus walks the repository tree breadth-first looking for nested workspace roots (directories declaring pnpm-workspace.yaml, lerna.json, or a package.json `workspaces` field), but stops once it has scanned WORKSPACE_ROOT_SCAN_MAX_DIRS directories. The warning tells you the scan hit that cap, so any nested workspace roots deeper in the tree were skipped and their packages will not be in the import-resolution package map.
Solutions
- Reduce the number of directories the scanner must walk: move vendored or generated trees into directories the scanner ignores, or add them to the hardcoded ignored-directory list.
- Split the oversized repository into smaller indexed repos, or point gitnexus at the relevant subdirectory as its own repoRoot so its workspaces fall inside the cap.
- If a specific nested workspace is being missed, hoist its workspace declaration (pnpm-workspace.yaml / package.json workspaces) closer to the repo root or reference its packages from the root workspace manifest.
- Treat it as informational if the truncated directories contain no workspace declarations; the top-level repoRoot is always included, so root-level packages still resolve.
Example fix
// before: workspace declared only deep inside a capped tree
my-monorepo/services/group/sub-app/pnpm-workspace.yaml
// after: declare packages from the root workspace so depth does not matter
// my-monorepo/package.json
{ "workspaces": ["services/group/sub-app/packages/*"] } Defensive patterns
Strategy: validation
Validate before calling
// before analyzing, check how many candidate workspace dirs the repo has count dirs: `git ls-files | cut -d/ -f1-3 | sort -u | wc -l` — if it exceeds the scan cap, expect truncation; prefer indexing a narrower subdirectory as repoRoot.
Prevention
- Keep vendored/generated trees in directories the workspace scanner ignores
- Split very large monorepos into separately indexed repos
- Declare nested workspaces near the repo root so they are reached early in the BFS
When it happens
Trigger: Running `gitnexus analyze` on a very large repository (monorepo or repo with many vendored/deeply-nested directories) whose BFS walk from repoRoot exceeds WORKSPACE_ROOT_SCAN_MAX_DIRS before enumerating all directories that declare a workspace. The cap check fires at the top of the while loop in findWorkspaceRoots before processing the next queued directory.
Common situations: Huge monorepos with thousands of directories; repos containing vendored node_modules-like trees or generated code outside the ignored directory list; monorepos where real nested workspaces (e.g. packages/group/sub-app with its own pnpm-workspace.yaml) sit late in the sorted directory order and get cut off.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- [node] package.json scan of
- [node-workspace-extractor] duplicate package name
- [csharp] namespace scan of
- [node] package : candidate source entries ( ) — none…
- [python-workspace-extractor] duplicate package
AI-assisted analysis of abhigyanpatwari/GitNexus@ac9a4e9abd (2026-09-15).
Data as JSON: /api/errors/02486da170fa6356.
Report an issue: GitHub.
Appendix: source
Thrown at gitnexus/src/core/ingestion/import-resolvers/node-workspace-packages.ts:442
}
async function readDirSorted(dir: string): Promise<import('fs').Dirent[] | null> {
try {
return (await fs.readdir(dir, { withFileTypes: true })).sort((a, b) =>
a.name < b.name ? -1 : a.name > b.name ? 1 : 0,
);
} catch {
return null;
}
}
async function findWorkspaceRoots(repoRoot: string): Promise<string[]> {
const roots: string[] = [repoRoot];
const queue: { dir: string; depth: number }[] = [{ dir: repoRoot, depth: 0 }];
let scanned = 0;
while (scanned < queue.length) {
if (scanned >= WORKSPACE_ROOT_SCAN_MAX_DIRS) {
logger.warn(
`[node] workspace-root scan of ${repoRoot} hit the ${WORKSPACE_ROOT_SCAN_MAX_DIRS}-directory cap; nested workspace roots below it were not considered`,
);
break;
}
const { dir, depth } = queue[scanned++]!;
const entries = await readDirSorted(dir);
if (entries === null) continue;
if (dir !== repoRoot) {
const names = new Set(entries.filter((e) => e.isFile()).map((e) => e.name));
let declares =
names.has('pnpm-workspace.yaml') ||
names.has('pnpm-workspace.yml') ||
names.has('lerna.json');
if (!declares && names.has('package.json')) {
const manifest = await readJsonFile(path.join(dir, 'package.json'));
declares = manifest?.workspaces !== undefined && manifest.workspaces !== null;
}
if (declares) roots.push(dir);View on GitHub (pinned to ac9a4e9abd)