abhigyanpatwari/GitNexus · error · Error
${TRUSTED_CACHE_DIRECTORY_ENV} must name a pre-existing prot
Error message
${TRUSTED_CACHE_DIRECTORY_ENV} must name a pre-existing protected non-symlink directory What it means
Thrown by trustedEnvironmentCacheDirectory when the configured path is syntactically absolute (passes error 91's check) but lstat/realpath fail or show it is not a real directory. The cache directory must pre-exist as a plain directory the analyzer can write to; the analyzer will NOT create the env-var-configured location (unlike the options.cacheDirectory override, which it does mkdir).
Source
Thrown at gitnexus/src/core/analyzer-identity.ts:2077
return process.platform === 'win32' ? left.toLowerCase() === right.toLowerCase() : left === right;
}
function trustedEnvironmentCacheDirectory(): string | null {
const configured = process.env[TRUSTED_CACHE_DIRECTORY_ENV];
if (configured === undefined) return null;
if (configured.length === 0 || configured.includes('\0') || !path.isAbsolute(configured)) {
throw new Error(`${TRUSTED_CACHE_DIRECTORY_ENV} must name an absolute protected directory`);
}
const normalized = path.normalize(configured);
let resolved: string;
try {
const link = lstatSync(normalized);
if (!link.isDirectory() || link.isSymbolicLink()) {
throw new Error('not a real directory');
}
resolved = realpathSync.native(normalized);
} catch {
throw new Error(
`${TRUSTED_CACHE_DIRECTORY_ENV} must name a pre-existing protected non-symlink directory`,
);
}
// Reject junctions/symlinked ancestors as well as a symlink final component.
// The environment variable is an explicit trust assertion, but its spelling
// must still bind exactly to the directory the cache will use.
if (!pathsEqual(path.resolve(normalized), resolved)) {
throw new Error(`${TRUSTED_CACHE_DIRECTORY_ENV} must not traverse symbolic links or junctions`);
}
return resolved;
}
function cacheDirectory(
options: AnalyzerIdentityResolveOptions,
packageRoot: string,
buildRoot: string,
): string | null {
// An explicit location is a trusted operator/test override and thereforeView on GitHub (pinned to d540b00184)
Solutions
- Pre-create the directory: `mkdir -p /var/cache/gitnexus-analyzer-identity && chmod 700 /var/cache/gitnexus-analyzer-identity`.
- Ensure the path is a REAL directory, not a symlink: `ls -ld <path>` should show `drwx...` with no `->`.
- If you need it auto-created, pass options.cacheDirectory instead of the env var — cacheDirectory() runs mkdirSync(explicit, {recursive:true, mode:0o700}).
- Confirm the mount is up before analyzer start (for network filesystems).
Example fix
# before: env points at a path that was never created # export GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR=/opt/gn-id # -> "...must name a pre-existing protected non-symlink directory" # # after: pre-create with restrictive perms # sudo mkdir -p /opt/gn-id && sudo chmod 700 /opt/gn-id && sudo chown $USER /opt/gn-id
Defensive patterns
Strategy: validation
Validate before calling
const fs = require('node:fs');
const path = require('node:path');
function validateTrustedCacheExists() {
const v = process.env.GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR;
if (!v) return;
const st = fs.lstatSync(v); // throws if missing -> caller must mkdir first
if (!st.isDirectory()) throw new Error(`${v} is not a directory`);
if (st.isSymbolicLink()) throw new Error(`${v} is a symlink; use the real path`);
}
// Pre-create before validating:
// const v = process.env.GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR;
// if (v) fs.mkdirSync(v, { recursive: true, mode: 0o700 }); Prevention
- Pre-create the cache dir before analyzer start: `mkdir -p <dir> && chmod 700 <dir>`.
- Use the real path, never a symlink — lstat must report a plain directory.
- If you want auto-creation, pass options.cacheDirectory instead of the env var.
- On network filesystems, confirm the mount is up before start.
When it happens
Trigger: trustedEnvironmentCacheDirectory lstatSync(normalized) either throws (ENOENT/permission) or returns a non-directory / a symlink; realpathSync.native then throws. The catch wraps both into this single message. So: a non-existent path, a file, a symlink-to-dir, or an unreadable path all surface here.
Common situations: Operator pointed the env var at a directory they forgot to `mkdir -p`; pointed it at a symlink (forbidden because the trust must bind to the exact real directory); pointed it at a path on a mount not yet available at analyzer start (NFS/cifs race); the directory was removed between deploys.
Related errors
- ${TRUSTED_CACHE_DIRECTORY_ENV} must name an absolute protect
- ${TRUSTED_CACHE_DIRECTORY_ENV} must not traverse symbolic li
- ${TRUSTED_CACHE_DIRECTORY_ENV} must be outside the analyzer
- Analyzer runtime payload directory is unavailable: ${absolut
- Analyzer runtime payload scan exceeded ${limits.runtimeEntri
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/f182bfe6012d66cb.
Report an issue: GitHub.