paperclipai/paperclip · error

OpenCode request ${input.requestId} is no longer pending

Error message

OpenCode request ${input.requestId} is no longer pending

What it means

Runtime requests (permission approvals, native questions) are tracked in `#pendingRuntimeRequests`. `resolveRuntimeRequest` throws when the given `requestId` is no longer in that map — it was already resolved, rejected, handed off, expired, or dropped when the session closed. This prevents double-submission of an answer to OpenCode's permission/question reply APIs.

Source

Thrown at packages/paperclip-runner/src/drivers/opencode/opencode-server-driver.ts:626

      `/session/${encodeURIComponent(this.#providerSessionId)}/abort`,
      { method: "POST" },
    );
  }

  pendingRuntimeRequests(): HarnessRuntimeRequest[] {
    return [...this.#pendingRuntimeRequests.values()].map(({ request }) =>
      structuredClone(request),
    );
  }

  async resolveRuntimeRequest(input: {
    requestId: string;
    turnId: string;
    resolution: HarnessRuntimeRequestResolution;
  }): Promise<void> {
    const pending = this.#pendingRuntimeRequests.get(input.requestId);
    if (!pending)
      throw new Error(
        `OpenCode request ${input.requestId} is no longer pending`,
      );
    if (
      pending.request.turnId !== input.turnId ||
      this.#activeTurnId !== input.turnId
    ) {
      throw new Error(
        `OpenCode request ${input.requestId} belongs to a stale turn`,
      );
    }
    const resolution = parseHarnessRuntimeRequestResolution(
      pending.request.requestKind,
      input.resolution,
      pending.request.input,
    );
    if (pending.settling)
      throw new Error(
        `OpenCode request ${input.requestId} is already settling`,

View on GitHub (pinned to 01ad858492)

Solutions

  1. List currently answerable requests with `session.pendingRuntimeRequests()` and only call `resolveRuntimeRequest` for ids present there.
  2. Treat the error as idempotent success: if the request was already resolved, the intended effect likely happened — log and continue.
  3. Do not persist requestId resolution across process restarts without replaying `pendingRuntimeRequests()`; recover state before resolving.
  4. Debounce/deduplicate resolution calls (e.g. disable the button once resolution starts) to avoid double submission.

Example fix

// before
await session.resolveRuntimeRequest({ requestId, turnId, resolution }); // throws if gone

// after
const pending = session.pendingRuntimeRequests().find(r => r.requestId === requestId);
if (pending) {
  await session.resolveRuntimeRequest({ requestId, turnId, resolution });
}
Defensive patterns

Strategy: validation

Validate before calling

const exists = session.pendingRuntimeRequests().some(r => r.requestId === requestId);
if (!exists) return; // already resolved or expired

Type guard

function isPending(session, requestId) { return session.pendingRuntimeRequests().some(r => r.requestId === requestId); }

Try / catch

try {
  await session.resolveRuntimeRequest({ requestId, turnId, resolution });
} catch (e) {
  if (e.message.includes('is no longer pending')) {
    logger.info({ requestId }, 'runtime request already resolved; treating as no-op');
  } else throw e;
}

Prevention

When it happens

Trigger: Calling `resolveRuntimeRequest({ requestId, turnId, resolution })` for a request that was already resolved earlier in this run, auto-expired via `handoffRuntimeRequest`, cancelled by `close()`, or that never existed on this session (e.g. after a restart the in-memory map is empty).

Common situations: A UI queues a permission answer and a durable handoff resolves the request first, then the queued answer is submitted; a process restart loses the pending map while the caller retries; the user double-clicks Approve and both clicks hit `resolveRuntimeRequest`.

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/f3ee018770b94a9b. Report an issue: GitHub.