abhigyanpatwari/GitNexus · error · Error

Analyzer dependency runtime changed while its identity was b

Error message

Analyzer dependency runtime changed while its identity was being computed: ${packageRoot}

What it means

Thrown by resolveAnalyzerRunnerIdentity when the dependency-runtime snapshot changed between the start of identity resolution (dependencySnapshotBefore) and a fresh re-collection after build hashing. Symmetric to error 96 but for the dependency tree (node_modules, manifests, vendored grammars): if dependencyInputs differ across the two passes, the dependency identity is not stable and the resolution aborts.

Source

Thrown at gitnexus/src/core/analyzer-identity.ts:2742

    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,
    traversalLimits,
    runtimeVariant,
    buildRootState: build.rootState,
    buildDigest: build.digest,
    buildEntries: build.entries,
    buildDirectoryGuards: build.directoryGuards,

View on GitHub (pinned to d540b00184)

Solutions

  1. Finish all installs before resolving identity: run `npm install` (or equivalent) to completion, then start the analyzer.
  2. Hold the analyzer until package managers are idle (no running npm/pnpm/yarn processes).
  3. In CI, sequence the analyzer strictly after the install step and before any watch/dev step.
  4. If a postinstall writes to vendor/, ensure it has exited before the analyzer starts.

Example fix

// before: CI starts analyzer while `pnpm install` still writing node_modules
//   -> "Analyzer dependency runtime changed while its identity was being computed: /repo"
//
// after: serialize install -> analyze
//   $ pnpm install --frozen-lockfile
//   $ node .gitnexus/run.cjs analyze --index-only
Defensive patterns

Strategy: retry

Validate before calling

function assertNoRunningInstaller() {
  // Refuse to resolve identity while a package manager may be mutating node_modules.
  const { execSync } = require('node:child_process');
  try {
    const out = execSync('pgrep -fl "npm install|pnpm install|yarn install"', { stdio: ['ignore','pipe','ignore'] }).toString();
    if (out.trim()) throw new Error(`Package manager still running:\n${out}`);
  } catch (e) {
    if (e.message.startsWith('Package manager')) throw e;
    // pgrep found nothing (exit 1) -> ok
  }
}
// assertNoRunningInstaller();

Try / catch

try {
  identity = resolveAnalyzerRunnerIdentity(analyzerModuleUrl, options);
} catch (err) {
  if (err.message.startsWith('Analyzer dependency runtime changed while its identity was being computed:')) {
    // install was still flushing; one retry after quiescence is reasonable.
    identity = resolveAnalyzerRunnerIdentity(analyzerModuleUrl, options);
  } else throw err;
}

Prevention

When it happens

Trigger: dependencySnapshot(collectDependencyInputs(...)) is computed twice; isDeepStrictEqual compares the two. Any change in resolved packages, edges, manifest bytes, lockfile bytes, vendored manifests, or directory/path guards between the two passes triggers the throw, naming packageRoot. Typically an install/add/remove happening during identity resolution.

Common situations: A package manager running in parallel (`npm install`, `pnpm add`, `yarn`) mutating node_modules; an IDE auto-installing a missing import; a postinstall script still writing vendored grammars; a CI that starts the analyzer before the install step finished; a docker layer that defers node_modules materialization.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12). Data as JSON: /api/errors/11c0093df7a74f93. Report an issue: GitHub.