abhigyanpatwari/GitNexus · error
Analyzer dependency resolution exceeded ${limits.resolutionA
Error message
Analyzer dependency resolution exceeded ${limits.resolutionAncestors} ancestors: ${packageName} What it means
resolveDependencyPackageRoot() implements Node-style upward resolution: from each ancestor directory it probes <dir>/node_modules/<packageName>/package.json, counting one ancestor per level and throwing past limits.resolutionAncestors (default 256). Each lexical hop is guarded because package managers expose packages through symlinks that can be retargeted. Exceeding 256 levels means the resolution walk ran unboundedly deep, which only happens in constructed layouts.
Source
Thrown at gitnexus/src/core/analyzer-identity.ts:1119
if (isLocallyLinkedSpecifier(specifier)) names.add(name);
}
}
return [...names].sort(compareBytes);
}
function resolveDependencyPackageRoot(
fromRoot: string,
packageName: string,
pathGuards: Map<string, DependencyPathGuardResult>,
limits: AnalyzerIdentityTraversalLimits,
): string | null {
let cursor = fromRoot;
const segments = packageName.split('/');
let ancestors = 0;
while (true) {
ancestors += 1;
if (ancestors > limits.resolutionAncestors) {
throw new Error(
`Analyzer dependency resolution exceeded ${limits.resolutionAncestors} ancestors: ${packageName}`,
);
}
const nodeModulesRoot = path.join(cursor, 'node_modules');
recordDependencyPathGuard(pathGuards, nodeModulesRoot);
let candidateParent = nodeModulesRoot;
for (const segment of segments) {
candidateParent = path.join(candidateParent, segment);
// Guard every lexical hop, not only the final manifest. Package
// managers commonly expose packages through symlinks; a retarget can
// otherwise preserve a hard-linked manifest's stat identity while
// changing the runtime payload tree selected by Node.
recordDependencyPathGuard(pathGuards, candidateParent);
}
const manifestPath = path.join(candidateParent, 'package.json');
recordDependencyPathGuard(pathGuards, manifestPath);
if (isFile(manifestPath)) return resolveExistingPath(path.dirname(manifestPath));
const parent = path.dirname(cursor);View on GitHub (pinned to 52924ef12c)
Solutions
- Install/run gitnexus at a conventional path depth.
- Adjust test traversalLimits so resolutionAncestors exceeds the fixture's real ancestor count.
- Check for mount-induced loops if the depth seems normal.
Defensive patterns
Strategy: try-catch
Type guard
function isDependencyAncestorLimitError(error: unknown): boolean {
return error instanceof Error && /^Analyzer dependency resolution exceeded \d+ ancestors:/.test(error.message);
} Try / catch
try {
identity = resolveAnalyzerRunnerIdentity(import.meta.url);
} catch (error) {
if (isDependencyAncestorLimitError(error)) {
reportUserError('Module resolution walked too many ancestors; move the install to a normal path depth.');
}
throw error;
} Prevention
- Install at conventional filesystem depths; avoid nested temp scaffolds for production use.
- Keep test resolutionAncestors overrides larger than the fixture's real depth.
When it happens
Trigger: Resolving a dependency name when the package root sits deeper than 256 directory levels below the filesystem root, or when tests tighten resolutionAncestors below the fixture's actual node_modules depth. The counter increments per ancestor directory visited, not per dependency, so normal hoisting never approaches it.
Common situations: Test fixtures with small resolutionAncestors overrides; pathologically nested temp directories; filesystem loops via bind mounts.
Related errors
- Analyzer dependency graph exceeded ${limits.runtimePackages}
- Analyzer runtime payload scan exceeded ${limits.runtimeEntri
- Analyzer runtime payload scan exceeded depth ${limits.runtim
- Analyzer runtime payload scan exceeded ${limits.runtimePaylo
- Analyzer runtime scan exceeded ${maxBytes} bytes: ${candidat
AI-assisted analysis of abhigyanpatwari/GitNexus@52924ef12c (2026-08-20).
Data as JSON: /api/errors/d67b8ba5aa9fed5e.
Report an issue: GitHub.