{"record":{"id":"494b1e226613111e","repo":"abhigyanpatwari/GitNexus","slug":"analyzer-vendored-runtime-directory-is-unavailable","errorCode":null,"errorMessage":"Analyzer vendored runtime directory is unavailable: ${vendorRoot}","messagePattern":"Analyzer vendored runtime directory is unavailable: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gitnexus/src/core/analyzer-identity.ts","lineNumber":1438,"sourceCode":"  packageRoot: string,\n  directoryGuards: Map<string, DependencyDirectoryGuard>,\n  options: AnalyzerIdentityResolveOptions,\n  budget: RuntimeArtifactScanBudget,\n  limits: AnalyzerIdentityTraversalLimits,\n): {\n  manifests: DependencyInputs['vendoredManifests'];\n  artifacts: RuntimeArtifact[];\n} {\n  const vendorRoot = path.join(packageRoot, 'vendor');\n  if (!existsSync(vendorRoot) || !lstatSync(vendorRoot).isDirectory()) {\n    recordDirectoryGuard(directoryGuards, packageRoot);\n    return { manifests: [], artifacts: [] };\n  }\n\n  const manifests: DependencyInputs['vendoredManifests'] = [];\n  const artifacts: RuntimeArtifact[] = [];\n  if (!recordDirectoryGuard(directoryGuards, vendorRoot)) {\n    throw new Error(`Analyzer vendored runtime directory is unavailable: ${vendorRoot}`);\n  }\n  const vendorEntries = readDirectory(vendorRoot, options);\n  budget.entries += vendorEntries.length;\n  if (budget.entries > limits.runtimeEntries) {\n    throw new Error(\n      `Analyzer runtime payload scan exceeded ${limits.runtimeEntries} entries: ${vendorRoot}`,\n    );\n  }\n  for (const entry of vendorEntries) {\n    if (!entry.isDirectory() || !entry.name.startsWith('tree-sitter-')) continue;\n    const grammarRoot = path.join(vendorRoot, entry.name);\n    const manifestPath = path.join(grammarRoot, 'package.json');\n    if (isFile(manifestPath)) {\n      options.onCacheMissWork?.({ kind: 'manifest-read', path: manifestPath });\n      const read = readStableFileWithinBudget(manifestPath, budget, limits.runtimeBytes);\n      manifests.push({\n        canonicalPath: `vendor:${entry.name}/package.json`,\n        absolutePath: manifestPath,","sourceCodeStart":1420,"sourceCodeEnd":1456,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/gitnexus/src/core/analyzer-identity.ts#L1420-L1456","documentation":"Thrown by collectVendoredGrammarInputs when recordDirectoryGuard returns false for the `vendor/` directory of the package root. Mirrors error 82 but for the vendored-tree entry point: the analyzer cannot inventory the vendor directory (readdir/stat threw), so it aborts rather than emit an incomplete identity for the vendored grammars.","triggerScenarios":"collectVendoredGrammarInputs computes vendorRoot = path.join(packageRoot,'vendor'); existsSync confirms it and lstat says directory, but the subsequent recordDirectoryGuard(vendorRoot) fails because snapshotDirectoryInventory throws (permissions lost, directory deleted between existsSync and the guard, or readdir denied).","commonSituations":"A race where a concurrent `tsc`/postinstall deletes and recreates `vendor/` while identity resolution runs; a container where the `vendor/` tree is owned by a different uid and the analyzer process lacks read/execute permission; an interrupted grammar-prebuild script that left `vendor/` half-populated and unreadable.","solutions":["Verify permissions and readability: `ls -la <packageRoot>/vendor` and ensure the analyzer uid can read+execute it.","Re-materialize the vendored grammars: re-run the package's postinstall or `npm rebuild <pkg>` to repopulate vendor/.","Run with no concurrent writers touching vendor/ during identity resolution.","If the platform lacks the optional-grammar toolchain, set GITNEXUS_SKIP_OPTIONAL_GRAMMARS=1 so the optional grammars are absent rather than half-installed."],"exampleFix":"// before: vendor/ owned by root, analyzer runs as non-root\n//   -> \"Analyzer vendored runtime directory is unavailable: /pkg/vendor\"\n//\n// after: fix ownership and rebuild grammars\n//   $ sudo chown -R $(id -u):$(id -g) vendor/\n//   $ npm rebuild","handlingStrategy":"try-catch","validationCode":"const fs = require('node:fs');\nconst path = require('node:path');\nfunction assertVendorReadable(packageRoot) {\n  const vendor = path.join(packageRoot, 'vendor');\n  if (!fs.existsSync(vendor)) return;\n  const st = fs.lstatSync(vendor);\n  if (!st.isDirectory()) throw new Error(`${vendor} is not a directory`);\n  try { fs.readdirSync(vendor); }\n  catch (e) { throw new Error(`${vendor} is not readable by uid ${process.getuid?.()}: ${e.message}`); }\n}\n// assertVendorReadable(process.cwd());","typeGuard":null,"tryCatchPattern":"try {\n  identity = resolveAnalyzerRunnerIdentity(analyzerModuleUrl, options);\n} catch (err) {\n  if (err.message.startsWith('Analyzer vendored runtime directory is unavailable:')) {\n    log.error('vendor/ unreadable; run `npm rebuild` or set GITNEXUS_SKIP_OPTIONAL_GRAMMARS=1');\n  }\n  throw err;\n}","preventionTips":["Ensure the analyzer process uid owns or can read+execute vendor/.","Re-run `npm rebuild` or the package postinstall if the vendored grammars are half-installed.","Set GITNEXUS_SKIP_OPTIONAL_GRAMMARS=1 when the optional-grammar toolchain is unavailable.","Do not run the analyzer while a postinstall is still writing vendor/."],"tags":["analyzer-identity","filesystem","directory-guard","vendored-grammars"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}