{"record":{"id":"f288ac6e950eeea6","repo":"abhigyanpatwari/GitNexus","slug":"analyzer-package-lock-lookup-exceeded-limits-res","errorCode":null,"errorMessage":"Analyzer package-lock lookup exceeded ${limits.resolutionAncestors} ancestors: ${packageRoot}","messagePattern":"Analyzer package-lock lookup exceeded (.+?) ancestors: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"gitnexus/src/core/analyzer-identity.ts","lineNumber":951,"sourceCode":"  candidate: string,\n): DependencyPathGuardResult {\n  if (guards.has(candidate)) return guards.get(candidate) ?? null;\n  const result = snapshotDependencyPathGuard(candidate);\n  guards.set(candidate, result);\n  return result;\n}\n\nfunction findNearestPackageLock(\n  packageRoot: string,\n  pathGuards: Map<string, DependencyPathGuardResult>,\n  limits: AnalyzerIdentityTraversalLimits,\n): string | null {\n  let cursor = packageRoot;\n  let ancestors = 0;\n  while (true) {\n    ancestors += 1;\n    if (ancestors > limits.resolutionAncestors) {\n      throw new Error(\n        `Analyzer package-lock lookup exceeded ${limits.resolutionAncestors} ancestors: ${packageRoot}`,\n      );\n    }\n    const candidate = path.join(cursor, 'package-lock.json');\n    recordDependencyPathGuard(pathGuards, candidate);\n    // Preserve the link path so ReadableFileState guards both the link and its\n    // resolved target. Realpathing here would miss a later retarget while the\n    // old target remained unchanged.\n    try {\n      const link = lstatSync(candidate);\n      if (link.isFile()) return path.resolve(candidate);\n      if (link.isSymbolicLink()) {\n        try {\n          const target = statSync(candidate);\n          if (!target.isFile()) {\n            throw new Error(\n              `Analyzer package lock symbolic link does not resolve to a file: ${candidate}`,\n            );","sourceCodeStart":933,"sourceCodeEnd":969,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/52924ef12c2290ceee4612526a828ec4cdf2047f/gitnexus/src/core/analyzer-identity.ts#L933-L969","documentation":"findNearestPackageLock() walks from the package root up through ancestors looking for package-lock.json, counting one ancestor per iteration and throwing past limits.resolutionAncestors (default 256). The walk must actually visit each level (it stats and records a guard per candidate), so the count also bounds the loop against pathological or cyclic-looking path structures. 256 levels is far deeper than any real install, so hitting it almost always means a constructed layout.","triggerScenarios":"The GitNexus package root sits more than 256 directory levels below the filesystem root, or a test set resolutionAncestors to a tiny value via traversalLimits. Because the loop increments before checking, even the first level counts, so a limit of 1 throws on any non-root start.","commonSituations":"Tests tightening resolutionAncestors for speed; pathologically nested temp/fixture directories (build tools that mirror deep scoped package names); a filesystem loop presented through mounts.","solutions":["Move the gitnexus install to a normal-depth location; real installs are dozens of levels deep at most.","In tests, only tighten resolutionAncestors when the fixture genuinely has few ancestor levels, and keep it above the actual depth.","Verify no mount/bind arrangement creates an effectively unbounded parent chain."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isLockfileAncestorLimitError(error: unknown): boolean {\n  return error instanceof Error && /^Analyzer package-lock lookup exceeded \\d+ ancestors:/.test(error.message);\n}","tryCatchPattern":"try {\n  identity = resolveAnalyzerRunnerIdentity(import.meta.url);\n} catch (error) {\n  if (isLockfileAncestorLimitError(error)) {\n    reportUserError('Install path is pathologically deep; move gitnexus to a normal-depth directory.');\n  }\n  throw error;\n}","preventionTips":["Install global tools at conventional paths, not inside deeply nested temp trees.","In tests, keep resolutionAncestors above the fixture's real ancestor depth."],"tags":["gitnexus","analyzer-identity","limits","package-lock","path-depth"],"backgroundTag":"traversal-limit-exceeded","analyzedSha":"52924ef12c2290ceee4612526a828ec4cdf2047f","analyzedAt":"2026-08-20T23:29:22.980Z","contentChangedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}