paperclipai/paperclip · error

Warm run transition template conflicts with its exact comman

Error message

Warm run transition template conflicts with its exact command.

What it means

During an in-flight (authenticated) warm transition, rotateRunIdentity() was given a runAttachTemplate that does not byte-for-byte match (canonical JSON) the template embedded in the transition's command payload after removing the paperclipNextAuthority boundary. The transition command is the exact source of truth for the attach template, so a divergent template fails closed.

Source

Thrown at packages/paperclip-runner/src/control-plane/durable-prp-control-plane.ts:1655

      if (transition.phase === "awaiting_result")
        throw new Error("Warm transition result is not yet authenticated.");
      if (
        canonicalJson(identity) !==
        canonicalJson(transition.receipt.newIdentity)
      ) {
        throw new Error(
          "Warm run transition target conflicts with its durable receipt.",
        );
      }
      // The new authenticated peer, not an attach-result observer, owns the
      // activation boundary. Keep the old credential and command replay lane.
      if (runAttachTemplate !== undefined) {
        const { paperclipNextAuthority: _boundary, ...expectedTemplate } =
          transition.command.payload;
        if (
          canonicalJson(runAttachTemplate) !== canonicalJson(expectedTemplate)
        ) {
          throw new Error(
            "Warm run transition template conflicts with its exact command.",
          );
        }
        const candidate = structuredClone(this.#store.state);
        candidate.runAttachTemplate = structuredClone(runAttachTemplate);
        this.#store.commit(candidate);
      }
      return;
    }
    if (
      this.#store.state.commands.some(
        (command) => command.type === "run.attach",
      )
    ) {
      throw new Error(
        "Warm run identity rotation requires a durable transition receipt.",
      );
    }

View on GitHub (pinned to 01ad858492)

Solutions

  1. Pass undefined for runAttachTemplate, or clone the template from transition.command.payload (stripping paperclipNextAuthority) exactly.
  2. Diff canonicalJson(runAttachTemplate) against the expected payload-derived template to find the divergent key.
  3. If the template must change, restart the warm transition with the new command rather than mutating the in-flight one.
  4. Freeze the template object at transition initiation and reuse that reference on every rotation call.

Example fix

// before
const { paperclipNextAuthority, ...mine } = transition.command.payload;
controlPlane.rotateRunIdentity(identity, { ...mine, extra: true }); // diverges
// after
const { paperclipNextAuthority: _b, ...expected } = transition.command.payload;
controlPlane.rotateRunIdentity(identity, structuredClone(expected));
Defensive patterns

Strategy: validation

Validate before calling

const t = store.state.warmTransition;
if (t && runAttachTemplate !== undefined) {
  const { paperclipNextAuthority: _b, ...expected } = t.command.payload;
  if (canonicalJson(runAttachTemplate) !== canonicalJson(expected)) {
    runAttachTemplate = structuredClone(expected); // conform to command payload
  }
}

Try / catch

try {
  controlPlane.rotateRunIdentity(identity, runAttachTemplate);
} catch (err) {
  if (err instanceof Error && err.message.includes("Warm run transition template conflicts")) {
    const { paperclipNextAuthority: _b, ...expected } = store.state.warmTransition.command.payload;
    controlPlane.rotateRunIdentity(identity, structuredClone(expected));
  } else throw err;
}

Prevention

When it happens

Trigger: Calling rotateRunIdentity(identity, runAttachTemplate) while warmTransition exists and its phase is past awaiting_result, but runAttachTemplate differs from transition.command.payload minus paperclipNextAuthority — e.g. extra keys, changed provider field, or a template rebuilt from newer config.

Common situations: Config or provider settings changed after the transition command was issued; the caller reconstructs the template instead of cloning the original; middleware injects extra fields into the template; a retry passes a merged/partial template.

Related errors


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