abhigyanpatwari/GitNexus · error
Analyzer vendored runtime directory is unavailable: ${vendor
Error message
Analyzer vendored runtime directory is unavailable: ${vendorRoot} What it means
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.
Source
Thrown at gitnexus/src/core/analyzer-identity.ts:1438
packageRoot: string,
directoryGuards: Map<string, DependencyDirectoryGuard>,
options: AnalyzerIdentityResolveOptions,
budget: RuntimeArtifactScanBudget,
limits: AnalyzerIdentityTraversalLimits,
): {
manifests: DependencyInputs['vendoredManifests'];
artifacts: RuntimeArtifact[];
} {
const vendorRoot = path.join(packageRoot, 'vendor');
if (!existsSync(vendorRoot) || !lstatSync(vendorRoot).isDirectory()) {
recordDirectoryGuard(directoryGuards, packageRoot);
return { manifests: [], artifacts: [] };
}
const manifests: DependencyInputs['vendoredManifests'] = [];
const artifacts: RuntimeArtifact[] = [];
if (!recordDirectoryGuard(directoryGuards, vendorRoot)) {
throw new Error(`Analyzer vendored runtime directory is unavailable: ${vendorRoot}`);
}
const vendorEntries = readDirectory(vendorRoot, options);
budget.entries += vendorEntries.length;
if (budget.entries > limits.runtimeEntries) {
throw new Error(
`Analyzer runtime payload scan exceeded ${limits.runtimeEntries} entries: ${vendorRoot}`,
);
}
for (const entry of vendorEntries) {
if (!entry.isDirectory() || !entry.name.startsWith('tree-sitter-')) continue;
const grammarRoot = path.join(vendorRoot, entry.name);
const manifestPath = path.join(grammarRoot, 'package.json');
if (isFile(manifestPath)) {
options.onCacheMissWork?.({ kind: 'manifest-read', path: manifestPath });
const read = readStableFileWithinBudget(manifestPath, budget, limits.runtimeBytes);
manifests.push({
canonicalPath: `vendor:${entry.name}/package.json`,
absolutePath: manifestPath,View on GitHub (pinned to d540b00184)
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.
Example fix
// before: vendor/ owned by root, analyzer runs as non-root // -> "Analyzer vendored runtime directory is unavailable: /pkg/vendor" // // after: fix ownership and rebuild grammars // $ sudo chown -R $(id -u):$(id -g) vendor/ // $ npm rebuild
Defensive patterns
Strategy: try-catch
Validate before calling
const fs = require('node:fs');
const path = require('node:path');
function assertVendorReadable(packageRoot) {
const vendor = path.join(packageRoot, 'vendor');
if (!fs.existsSync(vendor)) return;
const st = fs.lstatSync(vendor);
if (!st.isDirectory()) throw new Error(`${vendor} is not a directory`);
try { fs.readdirSync(vendor); }
catch (e) { throw new Error(`${vendor} is not readable by uid ${process.getuid?.()}: ${e.message}`); }
}
// assertVendorReadable(process.cwd()); Try / catch
try {
identity = resolveAnalyzerRunnerIdentity(analyzerModuleUrl, options);
} catch (err) {
if (err.message.startsWith('Analyzer vendored runtime directory is unavailable:')) {
log.error('vendor/ unreadable; run `npm rebuild` or set GITNEXUS_SKIP_OPTIONAL_GRAMMARS=1');
}
throw err;
} Prevention
- 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/.
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- Analyzer runtime payload directory is unavailable: ${absolut
- Analyzer runtime payload scan exceeded ${limits.runtimeEntri
- Analyzer runtime payload scan exceeded ${limits.runtimeEntri
- Analyzer runtime payload scan exceeded depth ${limits.runtim
- Analyzer runtime payload scan exceeded ${limits.runtimePaylo
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/494b1e226613111e.
Report an issue: GitHub.