{"record":{"id":"0c0c440b7ae3ac5e","repo":"abhigyanpatwari/GitNexus","slug":"analyzer-build-or-dependency-runtime-changed-while","errorCode":null,"errorMessage":"Analyzer build or dependency runtime changed while its identity was being computed: ${packageRoot}${mismatch}","messagePattern":"Analyzer build or dependency runtime changed while its identity was being computed: (.+?)(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gitnexus/src/core/analyzer-identity.ts","lineNumber":2825,"sourceCode":"      rootPath: buildRoot,\n      canonicalization: BUILD_CANONICALIZATION,\n      digest: build.digest,\n    },\n    dependencyRuntime: dependency.identity,\n  };\n  let validationFailure: { mode: CacheGuardRequest['mode']; path: string } | undefined;\n  const validationOptions: AnalyzerIdentityResolveOptions = {\n    ...options,\n    onCacheValidationFailure: (failure) => {\n      validationFailure = failure;\n      options.onCacheValidationFailure?.(failure);\n    },\n  };\n  if (!validateIdentityCache(nextCache, validationOptions)) {\n    const mismatch = validationFailure\n      ? ` (failed ${validationFailure.mode} guard: ${validationFailure.path})`\n      : '';\n    throw new Error(\n      `Analyzer build or dependency runtime changed while its identity was being computed: ${packageRoot}${mismatch}`,\n    );\n  }\n  rememberIdentityCache(nextCache);\n  persistIdentityCache(packageRoot, buildRoot, nextCache, previousCache, options);\n  return identity;\n}\n\n/**\n * Semantic freshness comparison. Both receipts must be well-formed schema-v4\n * values; only the diagnostic entrypoint field is normalized away.\n */\nexport function analyzerRunnerIdentitiesEqual(\n  indexedIdentity: unknown,\n  currentIdentity: unknown,\n): boolean {\n  const indexed = normalizeAnalyzerRunnerIdentityForComparison(indexedIdentity);\n  const current = normalizeAnalyzerRunnerIdentityForComparison(currentIdentity);","sourceCodeStart":2807,"sourceCodeEnd":2843,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/52924ef12c2290ceee4612526a828ec4cdf2047f/gitnexus/src/core/analyzer-identity.ts#L2807-L2843","documentation":"Before persisting the new identity cache, validateIdentityCache() re-checks every recorded guard (file stat states, directory states, path guards) captured during computation. If any guard now fails — or validation itself reports a failure via onCacheValidationFailure — the environment changed between hashing and persistence, and the error is thrown with the failing guard mode and path appended. This closes the window where a valid-looking identity could be cached for a mutated tree.","triggerScenarios":"resolveAnalyzerRunnerIdentity() completing its hashing but failing validateIdentityCache(nextCache): a guarded file's size/mtime/inode changed, a guarded directory was replaced, or a guarded path vanished — all between guard capture and validation. Any concurrent writer (install, rebuild, sync tool) to packageRoot/buildRoot can cause it.","commonSituations":"Same family as errors 70/71 but detected via guards at persistence time: postinstall scripts finishing late, antivirus touching files, timestamp updates from backup tools, or a second gitnexus process writing to the same install.","solutions":["Re-run analyze after the concurrent modification finishes — the message's guard path tells you exactly which file/directory raced.","Disable or reschedule backup/antivirus scans over node_modules and the gitnexus install during analysis.","Ensure only one gitnexus process runs against an installation at a time.","For self-built installs, finish builds before analysis; do not run identity resolution while tsc watch is active."],"exampleFix":"# before\n$ npx gitnexus analyze\n# Analyzer build or dependency runtime changed ... (failed file guard: /.../dist/cli.js)\n\n# after: wait for the racing writer, then retry\n$ wait   # or stop the concurrent npm install / tsc watch\n$ npx gitnexus analyze","handlingStrategy":"retry","validationCode":"// The guard path in the message identifies the raced file; pre-check quiescence:\nimport { statSync } from 'node:fs';\nfunction fileQuiescent(path: string, ms = 1000): boolean {\n  const a = statSync(path); \n  Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);\n  const b = statSync(path);\n  return a.mtimeMs === b.mtimeMs && a.size === b.size;\n}","typeGuard":null,"tryCatchPattern":"try {\n  await analyze({ repo: '.' });\n} catch (err) {\n  const m = /failed (\\w+) guard: (.+)\\)/.exec(String((err as Error).message));\n  if (err instanceof Error && err.message.includes('changed while its identity was being computed') && m) {\n    logger.warn(`Raced ${m[1]} guard at ${m[2]}; retrying after quiescence`);\n    await waitForQuiescent(m[2]);\n    return analyze({ repo: '.' });\n  }\n  throw err;\n}","preventionTips":["Exclude the analyzer install from antivirus scans and backup timestamp churn during analysis.","Serialize gitnexus processes sharing one installation.","Read the guard mode/path suffix — it pinpoints exactly which writer to stop.","Treat repeated guard failures on the same path as a persistent mutator, not bad luck."],"tags":["analyzer-identity","race-condition","cache-validation","tamper-guard"],"backgroundTag":"concurrent-modification-detected","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"}