abhigyanpatwari/GitNexus · error
must name an absolute protected directory
Error message
${TRUSTED_CACHE_DIRECTORY_ENV} must name an absolute protected directory What it means
GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR is an explicit trust assertion pointing the analyzer-identity cache at a specific directory, so its spelling is validated strictly: it must be non-empty, contain no NUL bytes, and be an absolute path. Any relative path (or empty/NUL-containing value) is rejected immediately with this error before any filesystem access.
Solutions
- Use an absolute path: export GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR=/var/cache/gitnexus-identity.
- If composing from a variable, expand explicitly: export GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR="$PWD/.gitnexus/identity-cache".
- Expand ~ manually ($HOME/...) — the validator does not perform shell expansion.
- Unset the variable entirely if you want the default secure cache location.
Example fix
# before export GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR=.cache/identity npx gitnexus analyze # GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR must name an absolute protected directory # after export GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR="$PWD/.cache/identity" npx gitnexus analyze
Defensive patterns
Strategy: validation
Validate before calling
// Validate before launching the CLI:
import { isAbsolute } from 'node:path';
function validIdentityCacheEnv(value: string | undefined): boolean {
return value === undefined ||
(value.length > 0 && !value.includes('\0') && isAbsolute(value));
}
if (!validIdentityCacheEnv(process.env.GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR)) {
throw new Error('Set GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR to an absolute path or unset it');
} Try / catch
try {
execSync('npx gitnexus analyze');
} catch (err) {
if (String((err as Error).message).includes('must name an absolute protected directory')) {
process.env.GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR = resolve(process.env.GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR!);
return execSync('npx gitnexus analyze');
}
throw err;
} Prevention
- Centralize env setup in one script that always exports absolute paths built from $PWD or $HOME.
- Never use ~ or relative spellings in env files; validators do not shell-expand.
- Add a CI lint step that greps .env files for relative values of *_DIR variables.
- Unset the variable when the default location is acceptable.
When it happens
Trigger: Setting GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR to a relative path like '.cache/identity' or '~/.gitnexus-cache' (tilde is not expanded), an empty string, or a value with embedded NUL, then running any command that resolves the analyzer identity (analyze, query, MCP server start).
Common situations: CI scripts and .env files using relative paths; Windows-style paths on POSIX or vice versa; shell quoting mistakes that leave the variable empty (GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR= with trailing space).
Understand the failure class
Background: "is not a valid" / "Invalid ... value" environment variable errors: how libraries validate env vars and what to do when they reject yours — this error's family across 48 libraries.
Related errors
- must be outside the analyzer package and build roots
- must name a pre-existing protected non-symlink directory
- must not traverse symbolic links or junctions
- Analyzer build changed while its identity was being computed
- Analyzer build or dependency runtime changed during…
AI-assisted analysis of abhigyanpatwari/GitNexus@52924ef12c (2026-08-20).
Data as JSON: /api/errors/a217456637784dda.
Report an issue: GitHub.
Appendix: source
Thrown at gitnexus/src/core/analyzer-identity.ts:2068
try {
tempRoot = realpathSync.native(os.tmpdir());
} catch {
return null;
}
return ensurePrivateChild(tempRoot, `gitnexus-analyzer-identity-${uid}`);
}
const TRUSTED_CACHE_DIRECTORY_ENV = 'GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR';
function pathsEqual(left: string, right: string): boolean {
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)) {View on GitHub (pinned to 52924ef12c)