paperclipai/paperclip · error
Warm run transition capability is required before attachment
Error message
Warm run transition capability is required before attachment.
What it means
Before an attachment command is accepted, the control plane checks that the connection has completed the warm-transition handshake: an established secure channel, warmTransitionVersion === 1, and not being replay-only. If the connection has not negotiated this capability, attaching is rejected because warm transition attachment requires the prior capability handshake.
Source
Thrown at packages/paperclip-runner/src/control-plane/durable-prp-control-plane.ts:1844
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 (
!commandTypes.has(type) ||
(commandId !== undefined &&
(commandId.length > 160 || !stableIdPattern.test(commandId)))
) {
throw new Error("Durable PRP command is invalid.");
}
if (commandId !== undefined) {
const existing = this.#store.state.commands.find(
(candidate) => candidate.commandId === commandId,
);
if (existing !== undefined) {
if (
existing.type !== type ||
canonicalJson(existing.payload) !== canonicalJson(payload)View on GitHub (pinned to 01ad858492)
Solutions
- Wait for the connection handshake to complete (secureChannel established) before issuing the attach command.
- Verify both sides negotiate warmTransitionVersion 1; upgrade the peer/runner if it reports a different version.
- Reconnect or reset the connection if it is marked replayOnly.
- Check connection state flags (secureChannel, warmTransitionVersion, replayOnly) before calling attach.
Example fix
// before await connection.send(attachCommand); // sent before handshake finished // after await connection.whenHandshakeComplete(); // secureChannel set, warmTransitionVersion === 1, !replayOnly await connection.send(attachCommand);
Defensive patterns
Strategy: validation
Validate before calling
function canAttach(conn) {
return conn.secureChannel !== null && conn.warmTransitionVersion === 1 && !conn.replayOnly;
}
if (!canAttach(connection)) await waitForWarmCapability(connection); Type guard
function hasWarmCapability(conn) {
return conn.secureChannel !== null && conn.warmTransitionVersion === 1 && conn.replayOnly === false;
} Try / catch
try {
await sendAttach();
} catch (err) {
if (err.message.includes("capability is required")) {
await renegotiateWarmTransition();
await sendAttach();
} else throw err;
} Prevention
- Gate attach calls on handshake-complete events, not timers.
- Keep runner and control plane versions aligned so warmTransitionVersion negotiates to 1.
- Reset replayOnly connections before attempting attachment.
When it happens
Trigger: Calling the attach command on a connection whose secureChannel is null (handshake not finished), whose warmTransitionVersion is not 1 (old/new peer version), or which is flagged replayOnly.
Common situations: Attempting attachment before the TLS/secure channel handshake completes; version skew between runner and control plane so warmTransitionVersion stays at 0; connection downgraded to replay-only after a reconnect.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- ${prefix}: the capability must be an object.
- DUPLEX_CHANNEL_CAPABILITY_DENIED
- DUPLEX_CHANNEL_OPEN_FAILED
- test-drive requires its isolated embedded database. Remove D
- test-drive cannot reuse a data directory configured for an e
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/7481c7f6d6cab799.
Report an issue: GitHub.