{"record":{"id":"a217456637784dda","repo":"abhigyanpatwari/GitNexus","slug":"trusted-cache-directory-env-must-name-an-absolu","errorCode":null,"errorMessage":"${TRUSTED_CACHE_DIRECTORY_ENV} must name an absolute protected directory","messagePattern":"(.+?) must name an absolute protected directory","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gitnexus/src/core/analyzer-identity.ts","lineNumber":2068,"sourceCode":"  try {\n    tempRoot = realpathSync.native(os.tmpdir());\n  } catch {\n    return null;\n  }\n  return ensurePrivateChild(tempRoot, `gitnexus-analyzer-identity-${uid}`);\n}\n\nconst TRUSTED_CACHE_DIRECTORY_ENV = 'GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR';\n\nfunction pathsEqual(left: string, right: string): boolean {\n  return process.platform === 'win32' ? left.toLowerCase() === right.toLowerCase() : left === right;\n}\n\nfunction trustedEnvironmentCacheDirectory(): string | null {\n  const configured = process.env[TRUSTED_CACHE_DIRECTORY_ENV];\n  if (configured === undefined) return null;\n  if (configured.length === 0 || configured.includes('\\0') || !path.isAbsolute(configured)) {\n    throw new Error(`${TRUSTED_CACHE_DIRECTORY_ENV} must name an absolute protected directory`);\n  }\n  const normalized = path.normalize(configured);\n  let resolved: string;\n  try {\n    const link = lstatSync(normalized);\n    if (!link.isDirectory() || link.isSymbolicLink()) {\n      throw new Error('not a real directory');\n    }\n    resolved = realpathSync.native(normalized);\n  } catch {\n    throw new Error(\n      `${TRUSTED_CACHE_DIRECTORY_ENV} must name a pre-existing protected non-symlink directory`,\n    );\n  }\n  // Reject junctions/symlinked ancestors as well as a symlink final component.\n  // The environment variable is an explicit trust assertion, but its spelling\n  // must still bind exactly to the directory the cache will use.\n  if (!pathsEqual(path.resolve(normalized), resolved)) {","sourceCodeStart":2050,"sourceCodeEnd":2086,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/52924ef12c2290ceee4612526a828ec4cdf2047f/gitnexus/src/core/analyzer-identity.ts#L2050-L2086","documentation":"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.","triggerScenarios":"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).","commonSituations":"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).","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."],"exampleFix":"# before\nexport GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR=.cache/identity\nnpx gitnexus analyze\n# GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR must name an absolute protected directory\n\n# after\nexport GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR=\"$PWD/.cache/identity\"\nnpx gitnexus analyze","handlingStrategy":"validation","validationCode":"// Validate before launching the CLI:\nimport { isAbsolute } from 'node:path';\nfunction validIdentityCacheEnv(value: string | undefined): boolean {\n  return value === undefined ||\n    (value.length > 0 && !value.includes('\\0') && isAbsolute(value));\n}\nif (!validIdentityCacheEnv(process.env.GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR)) {\n  throw new Error('Set GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR to an absolute path or unset it');\n}","typeGuard":null,"tryCatchPattern":"try {\n  execSync('npx gitnexus analyze');\n} catch (err) {\n  if (String((err as Error).message).includes('must name an absolute protected directory')) {\n    process.env.GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR = resolve(process.env.GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR!);\n    return execSync('npx gitnexus analyze');\n  }\n  throw err;\n}","preventionTips":["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."],"tags":["analyzer-identity","cache","environment-variable","path-validation"],"backgroundTag":"invalid-env-var-value","analyzedSha":"52924ef12c2290ceee4612526a828ec4cdf2047f","analyzedAt":"2026-08-20T23:29:22.980Z","contentChangedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}