paperclipai/paperclip · error

runnerd-native runtime requests require a canonical question

Error message

runnerd-native runtime requests require a canonical question response

What it means

Thrown when a resolution for a runnerd-native runtime request does not carry a canonical 'response' field. This transport only accepts the canonical question-response shape for runtime inputs; other resolution variants (e.g. raw payload or acknowledgement-only resolutions) are rejected.

Source

Thrown at packages/paperclip-runner/src/live/runnerd-codex-transport.ts:3734

      throw failure;
    }
  }

  async resolveRuntimeRequest(input: {
    requestId: string;
    turnId: string;
    resolution: HarnessRuntimeRequestResolution;
  }): Promise<void> {
    if (this.#pendingWarmRecoveryCompletion !== null) {
      throw new Error("native_runner_warm_transition_completion_pending");
    }
    const pending = this.#bridgedRuntimeInputs.get(input.requestId);
    if (!pending)
      throw new Error(
        `PRP runtime request ${input.requestId} is no longer pending`,
      );
    if (!("response" in input.resolution)) {
      throw new Error(
        "runnerd-native runtime requests require a canonical question response",
      );
    }
    const commandId = `command_runtime_input_${createHash("sha256")
      .update(`${input.requestId}:${pending.durableTurnId}`)
      .digest("hex")
      .slice(0, 24)}`;
    await this.#command(
      "request.resolve",
      {
        requestId: input.requestId,
        turnId: pending.durableTurnId,
        response: input.resolution.response,
      },
      commandId,
    );
  }

View on GitHub (pinned to 01ad858492)

Solutions

  1. Build the resolution as a canonical question response containing a 'response' field
  2. Map legacy/alternate resolution kinds to the canonical response shape before calling resolveRuntimeRequest
  3. Verify the resolution type used matches the runnerd-native transport's expected HarnessRuntimeRequestResolution variant

Example fix

// before
await transport.resolveRuntimeRequest({ requestId, turnId, resolution: { kind: "ack" } });
// after
await transport.resolveRuntimeRequest({ requestId, turnId, resolution: { response: { answers: ["yes"] } } });
Defensive patterns

Strategy: validation

Validate before calling

function isCanonicalQuestionResponse(r: unknown): r is { response: unknown } {
  return typeof r === "object" && r !== null && "response" in r;
}
if (!isCanonicalQuestionResponse(resolution)) {
  throw new TypeError("runnerd-native resolutions require a 'response' field");
}

Type guard

function hasResponseField(r: HarnessRuntimeRequestResolution): r is Extract<HarnessRuntimeRequestResolution, { response: unknown }> {
  return "response" in r;
}

Try / catch

null

Prevention

When it happens

Trigger: Calling resolveRuntimeRequest with a resolution object lacking the 'response' property — e.g. passing { kind: 'dismiss' } or a custom resolution type instead of a canonical question response.

Common situations: Copying resolution code written for a different transport (non-native) that permits alternate resolution kinds; constructing the resolution object dynamically and omitting 'response' on one branch.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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