{"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":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gitnexus/src/core/analyzer-identity.ts","lineNumber":2066,"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":2048,"sourceCodeEnd":2084,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/gitnexus/src/core/analyzer-identity.ts#L2048-L2084","documentation":"Thrown by trustedEnvironmentCacheDirectory when GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR is set but the value is empty, contains a NUL byte, or is not an absolute path. This is the first syntax/trust gate on the operator-provided cache location; the env var is an explicit trust assertion, so its spelling must be a valid absolute filesystem path.","triggerScenarios":"resolveAnalyzerRunnerIdentity -> cacheDirectory -> trustedEnvironmentCacheDirectory reads process.env.GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR. If the value fails any of `length===0`, `includes('\\0')`, or `!path.isAbsolute(value)`, it throws before any stat call. Common when the env var was exported empty (`export GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR=`) or set to a relative path or a tilde path.","commonSituations":"A shell that did not substitute `$VAR` (so the literal `$VAR` or empty string was exported); using `~/.cache/...` (tilde is not expanded inside env values); a CI secret that resolved to empty; a Windows path without a drive letter; a copy-paste that included a leading space or quote.","solutions":["Set an absolute path with no tilde and no NUL: `export GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR=/var/cache/gitnexus-analyzer-identity`.","Verify the value: `printf '%s' \"$GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR\" | od -c` to spot embedded NULs or whitespace.","If unset is desired, `unset GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR` so the secure default temp location is used.","On Windows use a drive-absolute path like `C:\\ProgramData\\gitnexus-analyzer-identity`."],"exampleFix":"# before: relative path with unexpanded tilde\n#   export GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR='~/.cache/gn-id'\n#   -> \"GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR must name an absolute protected directory\"\n#\n# after: absolute, expanded\n#   export GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR=\"$HOME/.cache/gn-id\"","handlingStrategy":"validation","validationCode":"function validateTrustedCacheEnv() {\n  const v = process.env.GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR;\n  if (v === undefined) return null; // unset is fine\n  if (v.length === 0) throw new Error('GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR is empty');\n  if (v.includes('\\0')) throw new Error('GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR contains a NUL byte');\n  const path = require('node:path');\n  if (!path.isAbsolute(v)) throw new Error(`GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR is not absolute: ${v}`);\n  return v;\n}\n// validateTrustedCacheEnv();","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always export an absolute path; never a relative path or a tilde path.","Verify substitution actually happened: `printf '%s' \"$GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR\"`.","If you do not need a custom location, unset the variable to use the secure default temp dir.","On Windows include the drive letter (e.g. C:\\\\...)."],"tags":["analyzer-identity","cache","configuration","environment"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}