{"record":{"id":"eee10063f790fdf7","repo":"paperclipai/paperclip","slug":"prp-command-type-omitted-its-durable-result","errorCode":null,"errorMessage":"PRP command ${type} omitted its durable result","messagePattern":"PRP command (.+?) omitted its durable result","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/live/runnerd-codex-transport.ts","lineNumber":5460,"sourceCode":"    } else {\n      core.queueCommand(type, payload, commandId, true);\n    }\n    await this.#waitCommand(type, commandId);\n  }\n\n  async #commandResult(\n    type: string,\n    payload: Record<string, unknown>,\n    deadline?: number,\n  ): Promise<Record<string, unknown>> {\n    const core = this.#core;\n    if (core === null) throw new Error(\"PRP provider thread is not started\");\n    const commandId = `command_lab_${randomUUID().replaceAll(\"-\", \"\")}`;\n    core.queueCommand(type, payload, commandId, true);\n    await this.#waitCommand(type, commandId, deadline);\n    const command = core.getCommand(commandId);\n    if (command?.status !== \"completed\" || command.type !== type) {\n      throw new Error(`PRP command ${type} omitted its durable result`);\n    }\n    const result = record(record(command.result).result);\n    const completion = this.#pendingWarmRecoveryCompletion;\n    if (completion && type === \"session.snapshot\") {\n      const expectation = this.#checkpointProviderIdentityExpectation;\n      const providerIdentity = resolveRunnerdSessionIdentity(result);\n      if (\n        command.type !== \"session.snapshot\" ||\n        core.store.state.warmTransition !== undefined ||\n        !recoveryIdentityMatches(\n          core.store.state.identity,\n          completion.identity,\n        ) ||\n        core.store.state.completedWarmTransition?.receipt.transitionId !==\n          completion.transitionId ||\n        expectation === null ||\n        providerIdentity.threadId !== expectation.driverSessionId ||\n        providerIdentity.sessionId !== expectation.providerSessionId ||","sourceCodeStart":5442,"sourceCodeEnd":5478,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/live/runnerd-codex-transport.ts#L5442-L5478","documentation":"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`.","triggerScenarios":"`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).","commonSituations":"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.","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."],"exampleFix":"// before\nawait this.#waitCommand(type, commandId, deadline);\nconst command = core.getCommand(commandId);\n// after\nconst completed = await this.#waitCommand(type, commandId, deadline).catch(() => null);\nif (!completed) throw new Error(`PRP command ${type} omitted its durable result`);\nconst command = core.getCommand(commandId);","handlingStrategy":"retry","validationCode":"const cmd = core.getCommand(commandId);\nif (!cmd || cmd.type !== type) throw new Error(`command ${commandId} missing or mistyped`);","typeGuard":"function isCompletedCommand(c, type) {\n  return !!c && c.status === \"completed\" && c.type === type;\n}","tryCatchPattern":"try {\n  await this.#commandResult(type, payload, deadline);\n} catch (err) {\n  if (err.message.includes(\"omitted its durable result\")) {\n    await this.#commandResult(type, payload, deadline); // one retry with fresh commandId\n  } else throw err;\n}","preventionTips":["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."],"tags":["runnerd","protocol","durable-state","command"],"backgroundTag":"unexpected-response-shape","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}