paperclipai/paperclip · error
PRP command ${type} omitted its durable result
Error message
PRP command ${type} omitted its durable result What it means
Thrown from `#commandResult` after `#waitCommand` resolves but the stored command is not in `status === "completed"` with the expected `type`. The PRP command lifecycle promises a durable result record; if the command record is missing, typed differently, or never reached `completed`, the transport treats the protocol contract as broken and throws rather than reading a bogus `command.result`.
Source
Thrown at packages/paperclip-runner/src/live/runnerd-codex-transport.ts:5460
} else {
core.queueCommand(type, payload, commandId, true);
}
await this.#waitCommand(type, commandId);
}
async #commandResult(
type: string,
payload: Record<string, unknown>,
deadline?: number,
): Promise<Record<string, unknown>> {
const core = this.#core;
if (core === null) throw new Error("PRP provider thread is not started");
const commandId = `command_lab_${randomUUID().replaceAll("-", "")}`;
core.queueCommand(type, payload, commandId, true);
await this.#waitCommand(type, commandId, deadline);
const command = core.getCommand(commandId);
if (command?.status !== "completed" || command.type !== type) {
throw new Error(`PRP command ${type} omitted its durable result`);
}
const result = record(record(command.result).result);
const completion = this.#pendingWarmRecoveryCompletion;
if (completion && type === "session.snapshot") {
const expectation = this.#checkpointProviderIdentityExpectation;
const providerIdentity = resolveRunnerdSessionIdentity(result);
if (
command.type !== "session.snapshot" ||
core.store.state.warmTransition !== undefined ||
!recoveryIdentityMatches(
core.store.state.identity,
completion.identity,
) ||
core.store.state.completedWarmTransition?.receipt.transitionId !==
completion.transitionId ||
expectation === null ||
providerIdentity.threadId !== expectation.driverSessionId ||
providerIdentity.sessionId !== expectation.providerSessionId ||View on GitHub (pinned to 01ad858492)
Solutions
- Inspect runnerd logs around the command ID to see whether the durable result was persisted; restart runnerd if it crashed mid-command.
- Retry the command — a fresh commandId and queueCommand round-trip usually re-establishes the durable result.
- Verify transport and runnerd protocol versions agree on the command `type` string.
- If the wait helper can return on non-completion, tighten `#waitCommand` so it only resolves when the command is completed.
Example fix
// before
await this.#waitCommand(type, commandId, deadline);
const command = core.getCommand(commandId);
// after
const completed = await this.#waitCommand(type, commandId, deadline).catch(() => null);
if (!completed) throw new Error(`PRP command ${type} omitted its durable result`);
const command = core.getCommand(commandId); Defensive patterns
Strategy: retry
Validate before calling
const cmd = core.getCommand(commandId);
if (!cmd || cmd.type !== type) throw new Error(`command ${commandId} missing or mistyped`); Type guard
function isCompletedCommand(c, type) {
return !!c && c.status === "completed" && c.type === type;
} Try / catch
try {
await this.#commandResult(type, payload, deadline);
} catch (err) {
if (err.message.includes("omitted its durable result")) {
await this.#commandResult(type, payload, deadline); // one retry with fresh commandId
} else throw err;
} Prevention
- Always pass a unique commandId so lookups cannot hit stale records.
- Monitor runnerd for mid-command crashes.
- Keep the command store retention long enough to outlive in-flight waits.
When it happens
Trigger: `core.queueCommand(type, payload, commandId, true)` followed by `#waitCommand`, but `core.getCommand(commandId)` returns undefined (command purged/reset), a different `type`, or a non-completed status that `#waitCommand` did not reject on (e.g. wait resolved by deadline/other path).
Common situations: runnerd crashed mid-command so the durable result was never written; command store reset between queue and get; protocol mismatch where the completion arrives under a different command type; a bug letting `#waitCommand` return without completion.
Related errors
- PRP command ${type} ${command.status}: ${JSON.stringify(comm
- The duplex channel launch command needs at least one argumen
- runnerd digest mismatch: expected ${request.runnerd.sha256},
- Unsupported test-drive harness: ${String(harness)}.
- provider_initialize_protocol_error
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/eee10063f790fdf7.
Report an issue: GitHub.