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
- Pass undefined for runAttachTemplate, or clone the template from transition.command.payload (stripping paperclipNextAuthority) exactly.
- Diff canonicalJson(runAttachTemplate) against the expected payload-derived template to find the divergent key.
- If the template must change, restart the warm transition with the new command rather than mutating the in-flight one.
- 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
- Clone the template from the transition command payload instead of rebuilding it from config.
- Freeze the template object at transition initiation and reuse the same reference.
- Avoid injecting extra keys (logging metadata, feature flags) into attach templates.
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
- Completed warm transition template conflicts with its exact
- Warm run transition target conflicts with its durable receip
- Warm transition result is not yet authenticated.
- Warm run identity rotation requires a durable transition rec
- Durable PRP run identity rotation is invalid.
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/32b8fef86f1f6565.
Report an issue: GitHub.