paperclipai/paperclip · error

native_runtime_request_handoff_unavailable

native_runtime_request_handoff_unavailable

Error message

native_runtime_request_handoff_unavailable

What it means

handoffRuntimeRequest delegates a durable handoff of an outstanding runtime request to the HarnessSession's optional handoffRuntimeRequest capability. When the driver does not implement it, the backend throws native_runtime_request_handoff_unavailable: the session cannot transfer the pending request to another run/session.

Source

Thrown at packages/paperclip-runner/src/backends/harness-driver-backend.ts:738

      NonNullable<HarnessSession["resolveRuntimeRequest"]>
    >[0]["resolution"];
  }) {
    this.#assertProtocolIntegrity();
    if (this.#session.resolveRuntimeRequest === undefined) {
      throw new Error("native_runtime_request_resolution_unavailable");
    }
    return this.#withProtocolIntegrity(() => this.#session.resolveRuntimeRequest!(input));
  }

  handoffRuntimeRequest(input: {
    requestId: string;
    turnId: string;
    reason: "durable_handoff";
    signal: AbortSignal;
  }) {
    this.#assertProtocolIntegrity();
    if (this.#session.handoffRuntimeRequest === undefined) {
      throw new Error("native_runtime_request_handoff_unavailable");
    }
    return this.#session.handoffRuntimeRequest(input);
  }

  goal(input: Parameters<NonNullable<HarnessSession["goal"]>>[0]) {
    this.#assertProtocolIntegrity();
    if (this.#session.goal === undefined) {
      throw new Error("native_session_goal_unavailable");
    }
    return this.#withProtocolIntegrity(() => this.#session.goal!(input));
  }

  async result() {
    this.#assertProtocolIntegrity();
    if (this.#explicitlyCancelled) return null;
    const snapshot = await this.#harnessSnapshot();
    if (
      snapshot.semanticResult === undefined ||

View on GitHub (pinned to 01ad858492)

Solutions

  1. Upgrade the driver to a version implementing handoffRuntimeRequest
  2. Re-issue the request fresh in the new run instead of handing off the old one
  3. Expire/cancel the pending request and let the new run raise its own
  4. Feature-detect handoff support before attempting a durable handoff

Example fix

// before
await backend.handoffRuntimeRequest({ requestId, turnId, reason: 'durable_handoff', signal });
// after
if (!backend.canHandoffRuntimeRequests()) {
  await backend.resolveRuntimeRequest({ requestId, resolution: { kind: 'cancel' } }).catch(() => {});
} else {
  await backend.handoffRuntimeRequest({ requestId, turnId, reason: 'durable_handoff', signal });
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (typeof session.handoffRuntimeRequest !== 'function') planRequestReissueInstead();

Type guard

const canHandoff = (s: HarnessSession): s is HarnessSession & { handoffRuntimeRequest: NonNullable<HarnessSession['handoffRuntimeRequest']> } => typeof s.handoffRuntimeRequest === 'function';

Try / catch

try { await backend.handoffRuntimeRequest({ requestId, turnId, reason: 'durable_handoff', signal }); } catch (e) { if (e.message === 'native_runtime_request_handoff_unavailable') { await reissueRequestInNewRun(requestId); } else throw e; }

Prevention

When it happens

Trigger: Calling handoffRuntimeRequest({ requestId, reason: 'durable_handoff', ... }) on a session whose driver lacks handoffRuntimeRequest; attempting durable handoff across a driver restart boundary on a driver without handoff support.

Common situations: Migrating a pending permission/input request to a new run after a crash or deploy on a driver that predates handoff support; adapters where handoff is intentionally not implemented (session-bound requests).

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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