paperclipai/paperclip · error

PRP runtime request ${input.requestId} is no longer pending

Error message

PRP runtime request ${input.requestId} is no longer pending

What it means

Thrown when resolveRuntimeRequest cannot find the given requestId among the bridged runtime inputs. The runtime question was already resolved, cancelled, or never registered on this transport, so there is nothing to resolve. The message includes the offending requestId for correlation.

Source

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

            .catch(() => undefined);
        }
        this.#failTransport(failure);
      }
      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,
      },

View on GitHub (pinned to 01ad858492)

Solutions

  1. Check that the requestId matches a currently pending runtime input on this transport
  2. Treat the error as benign if the question was already resolved and skip re-resolution
  3. Refresh the pending-question list from the runner before answering after a reconnect or recovery
  4. Ensure only one component owns resolution of a given runtime request

Example fix

// before
await transport.resolveRuntimeRequest({ requestId, turnId, resolution });
// after
const pending = transport.getPendingRuntimeInput(requestId);
if (!pending) {
  console.warn(`Skipping already-resolved runtime request ${requestId}`);
  return;
}
await transport.resolveRuntimeRequest({ requestId, turnId, resolution });
Defensive patterns

Strategy: validation

Validate before calling

if (!transport.getPendingRuntimeInput?.(requestId)) {
  console.warn(`runtime request ${requestId} no longer pending; skipping`);
  return;
}

Type guard

null

Try / catch

try {
  await transport.resolveRuntimeRequest({ requestId, turnId, resolution });
} catch (err) {
  if (err instanceof Error && err.message.includes("is no longer pending")) {
    return; // already resolved or torn down — idempotent no-op
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling resolveRuntimeRequest with a requestId that is not present in #bridgedRuntimeInputs — e.g. a duplicate resolution, a resolution after the turn was torn down, or a stale/cross-runner requestId.

Common situations: Double-click/double-submit of a question answer in the UI; answering a question after the turn ended or the runner restarted; sending a resolution captured on one runner to a different (recovered) runner instance.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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