paperclipai/paperclip · error

native_runner_warm_transition_snapshot_mismatch

Error message

native_runner_warm_transition_snapshot_mismatch

What it means

Thrown when the warm-transition snapshot proof cannot be produced: proofWasmRunnerSnapshot returns no proof for the candidate runner state given the expected new identity, runner version, and runner digest. This means the on-disk/remote snapshot does not match what the transition expects to own.

Source

Thrown at packages/paperclip-runner/src/live/runnerd-codex-transport.ts:4671

          this.options.warmTransitionRegistrationMode !== "routed_connect") ||
        this.options.adoptExistingRunner !== undefined
      ) {
        throw new Error(
          "native_runner_warm_transition_requires_exact_owned_endpoint",
        );
      }
      const artifact = approvedRunnerArtifact(
        this.options.runnerBinary ?? defaultCapabilityRunnerdBinary(),
      );
      const proof = inspectWarmRunTransition({
        controlPlaneState,
        runnerState: candidateRunnerState,
        expectedNewIdentity: desiredIdentity,
        expectedRunnerVersion: artifact.version,
        expectedRunnerDigest: artifact.digest,
      });
      if (!proof)
        throw new Error("native_runner_warm_transition_snapshot_mismatch");
      const receipt = proof.receipt;
      const connection = receipt.connection;
      const endpoint =
        typeof connection.connectUrl === "string"
          ? new URL(connection.connectUrl)
          : null;
      if (
        connection.mode !== "connect" ||
        endpoint === null ||
        endpoint.search ||
        endpoint.hash ||
        endpoint.username ||
        endpoint.password ||
        (!this.options.controlPlaneRegistration &&
          (endpoint.protocol !== "ws:" ||
            endpoint.hostname !== "127.0.0.1" ||
            endpoint.pathname !== "/durableRecovery/connect" ||
            !endpoint.port))

View on GitHub (pinned to 01ad858492)

Solutions

  1. Re-capture the candidate runner state with the currently approved runner binary
  2. Verify the runner binary digest/version matches the approved artifact (approvedRunnerArtifact)
  3. Ensure prpIdentity passed to the transition matches the snapshot's session/turn/item identity
  4. Re-run the warm transition after the underlying turn state has been re-synced

Example fix

// before
const artifact = approvedRunnerArtifact(localRunnerBinaryPath); // stale binary
const proof = proofWasmRunnerSnapshot({ runnerState: candidateRunnerState, expectedRunnerDigest: artifact.digest });
// after
const artifact = approvedRunnerArtifact(this.options.runnerBinary ?? defaultCapabilityRunnerdBinary());
const freshState = await readRunnerState(root); // re-read state matching the approved binary
const proof = proofWasmRunnerSnapshot({ runnerState: freshState, expectedRunnerDigest: artifact.digest, expectedRunnerVersion: artifact.version });
Defensive patterns

Strategy: retry

Validate before calling

const artifact = approvedRunnerArtifact(runnerBinary);
if (candidateRunnerState.runnerVersion !== artifact.version ||
    candidateRunnerState.runnerDigest !== artifact.digest) {
  throw new Error("runner state does not match approved artifact; re-capture before transition");
}

Type guard

null

Try / catch

try {
  await transport.beginWarmTransition();
} catch (err) {
  if (err instanceof Error && err.message === "native_runner_warm_transition_snapshot_mismatch") {
    await recaptureRunnerState();
    await transport.beginWarmTransition();
  } else throw err;
}

Prevention

When it happens

Trigger: candidateRunnerState is stale or from a different runner binary version/digest than the approved artifact; desiredIdentity (prpIdentity) does not match the snapshot's identity; the runner state file was regenerated or overwritten between capture and proof.

Common situations: Runner binary upgraded between snapshot capture and warm transition; mixed-version fleet where the controller expects one digest but the runner wrote another; resuming a snapshot captured for a different turn/session.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/281e66cf050f5f5c. Report an issue: GitHub.