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

  1. Stop the concurrent writer (dev watcher, parallel install) and re-run analyze — identity computation is fast once stable.
  2. In CI, sequence steps so no build/install runs concurrently with analysis.
  3. Exclude the analyzer build tree from sync clients and editors' auto-build.
  4. 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

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


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)