paperclipai/paperclip · error

Warm run transition permits only its exact cached attachment

Error message

Warm run transition permits only its exact cached attachment replay.

What it means

During a warm run transition, command replay is deliberately restricted: only the exact cached run.attach command (matching commandId AND canonical JSON payload) associated with the transition may be replayed. Any other command id, command type, or altered payload during the warm transition is rejected to prevent tampering or duplicate attachment with different parameters.

Source

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

    return ticket;
  }

  queueCommand(
    type: string,
    payload: Record<string, unknown> = {},
    commandId?: string,
    deliverImmediately = false,
  ): DurableRecoveryCoreCommand {
    this.#store.assertWritable();
    const transition = this.#store.state.warmTransition;
    if (transition && transition.phase !== "activated") {
      if (
        commandId === transition.command.commandId &&
        type === "run.attach" &&
        canonicalJson(payload) === canonicalJson(transition.command.payload)
      )
        return transition.command;
      throw new Error(
        "Warm run transition permits only its exact cached attachment replay.",
      );
    }
    if (
      type === "run.attach" &&
      payload.paperclipNextAuthority !== undefined &&
      ![...this.#connections].some(
        (connection) =>
          connection.secureChannel !== null &&
          connection.warmTransitionVersion === 1 &&
          !connection.replayOnly,
      )
    ) {
      throw new Error(
        "Warm run transition capability is required before attachment.",
      );
    }
    if (

View on GitHub (pinned to 01ad858492)

Solutions

  1. Replay the attach command with byte-identical payload to the one cached on the transition (same key order/content).
  2. Reuse the original commandId stored on transition.command.
  3. Defer any modified or new attach commands until after the warm transition completes and the connection exits replay-only mode.
  4. Compare canonicalJson(payload) with canonicalJson(transition.command.payload) locally before sending.

Example fix

// before
await conn.send({ type: "run.attach", commandId: newId, payload: { ...cachedPayload, extra: true } });
// after
await conn.send({ type: "run.attach", commandId: transition.command.commandId, payload: transition.command.payload });
Defensive patterns

Strategy: validation

Validate before calling

function canReplayAttach(transition, msg) {
  return msg.commandId === transition.command.commandId &&
    msg.type === "run.attach" &&
    canonicalJson(msg.payload) === canonicalJson(transition.command.payload);
}
if (!canReplayAttach(transition, msg)) throw new Error("non-identical attach replay");

Type guard

function isExactCachedReplay(transition, msg) {
  return msg.type === "run.attach" && msg.commandId === transition.command.commandId;
}

Try / catch

try {
  await conn.send(msg);
} catch (err) {
  if (err.message.includes("exact cached attachment replay")) {
    // resend transition.command verbatim
  } else throw err;
}

Prevention

When it happens

Trigger: Replaying a run.attach command during a warm transition whose commandId differs from transition.command.commandId, or whose payload does not serialize identically (canonicalJson) to the cached transition.command.payload. Also thrown if a non-run.attach command is issued inside the exact-replay branch.

Common situations: Re-serializing the payload after JSON round-trips that change key order or numeric formatting; retry logic that sends an updated attach payload; sending new commands while a warm transition is in flight instead of after it completes.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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