abhigyanpatwari/GitNexus · error
Analyzer build changed while its identity was being computed
Error message
Analyzer build changed while its identity was being computed: ${buildRoot} What it means
Analyzer identity computation is designed to be atomic against filesystem mutation: it snapshots the build tree, then re-collects build entries and deep-compares. If the two snapshots differ, the build changed underneath the computation and the resulting identity would describe a state that never existed, so it throws with the build root. This is a deliberate race detector, not a flaky failure.
Solutions
- Stop the concurrent writer (dev watcher, parallel install) and re-run analyze — identity computation is fast once stable.
- In CI, sequence steps so no build/install runs concurrently with analysis.
- Exclude the analyzer build tree from sync clients and editors' auto-build.
- For development of GitNexus itself, complete the build before invoking analyze rather than during.
Example fix
# before: two terminals T1: npm run dev # tsx watch recompiles continuously T2: npx gitnexus analyze # Analyzer build changed while its identity was being computed # after: build first, then analyze T1: npm run build && npm run dev & T2: sleep 5 && npx gitnexus analyze
Defensive patterns
Strategy: retry
Validate before calling
// Skip analysis while a build watcher holds the tree:
import { execSync } from 'node:child_process';
function noActiveBuildWriter(): boolean {
try {
const ps = execSync('ps ax -o command=', { encoding: 'utf8' });
return !/\b(tsc|tsx|esbuild|npm run (dev|build))\b/.test(ps);
} catch {
return true;
}
} Try / catch
try {
await analyze({ repo: '.' });
} catch (err) {
if (err instanceof Error && /build changed while its identity was being computed/.test(err.message)) {
await waitForQuiescentTree(buildRoot); // poll mtimes until stable, then single retry
return analyze({ repo: '.' });
}
throw err;
} Prevention
- Sequence CI: build fully, then analyze; never run tsc watch during analysis of the install.
- Run analyze against released, immutable installs rather than actively-developed trees.
- Keep sync clients and editors' auto-build away from the analyzer installation.
- Retry at most once after quiescence — repeated failures mean a persistent writer, not a race.
When it happens
Trigger: Anything that writes to buildRoot between hashBuildTree() and the post-check: a concurrent npm install/rebuild, tsc --build running in watch mode, an editor or sync client touching files, or a dev-mode watcher recompiling while analyze runs.
Common situations: Running `gitnexus analyze` in one terminal while `npm run dev` (tsx watch) recompiles in another; CI where a post-install step rebuilds native modules during the run; Dropbox/OneDrive sync mutating mtimes; Docker volume writes from a sibling container.
Related errors
- Analyzer dependency runtime changed while its identity was…
- Analyzer identity directory changed while it was read
- Analyzer identity input changed while it was being read
- Analyzer vendored runtime directory is unavailable
- Analyzer build or dependency runtime changed during…
AI-assisted analysis of abhigyanpatwari/GitNexus@52924ef12c (2026-08-20).
Data as JSON: /api/errors/19c3d43d995f4775.
Report an issue: GitHub.
Appendix: source
Thrown at gitnexus/src/core/analyzer-identity.ts:2760
const dependencyInputs = collectDependencyInputs(packageRoot, options, traversalLimits);
const dependencySnapshotBefore = dependencySnapshot(dependencyInputs);
const dependency = hashDependencyRuntime(
dependencyInputs,
previousCache,
options,
runtimeVariant,
);
const packageVersion = dependencyInputs.packages[0]?.manifest.version;
if (typeof packageVersion !== 'string' || packageVersion.trim() === '') {
throw new Error(`GitNexus package version is unavailable in ${packageRoot}`);
}
const buildSnapshotAfter = buildSnapshot(
collectBuildEntries(buildRoot, options, traversalLimits),
);
if (!isDeepStrictEqual(build.snapshot, buildSnapshotAfter)) {
throw new Error(`Analyzer build changed while its identity was being computed: ${buildRoot}`);
}
const dependencySnapshotAfter = dependencySnapshot(
collectDependencyInputs(packageRoot, options, traversalLimits),
);
if (!isDeepStrictEqual(dependencySnapshotBefore, dependencySnapshotAfter)) {
throw new Error(
`Analyzer dependency runtime changed while its identity was being computed: ${packageRoot}`,
);
}
const nextCache: IdentityCachePayload = {
schemaVersion: IDENTITY_CACHE_SCHEMA_VERSION,
packageRoot,
buildRoot,
packageVersion,
buildKind: kind,
buildCanonicalization: BUILD_CANONICALIZATION,
dependencyCanonicalization: DEPENDENCY_RUNTIME_CANONICALIZATION,View on GitHub (pinned to 52924ef12c)