paperclipai/paperclip · error
Warm run transition template conflicts with its exact…
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.
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.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- Completed warm transition template conflicts with its exact…
- Warm run transition target conflicts with its durable…
- delivery_unknown
- Durable PRP run attachment template conflicts.
- Durable PRP run identity rotation is invalid.
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-10).
Data as JSON: /api/errors/32b8fef86f1f6565.
Report an issue: GitHub.
Appendix: source
Thrown at packages/paperclip-runner/src/control-plane/durable-prp-control-plane.ts:1673
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 3f1d897a7c)