paperclipai/paperclip · error
interruption is unavailable
Error message
interruption is unavailable
What it means
interrupt forwards an interrupt request to the HarnessSession's optional interrupt capability. If the driver does not implement interrupt (this.#session.interrupt === undefined), the backend throws "interruption is unavailable" because it cannot abort the in-flight turn through the protocol.
Source
Thrown at packages/paperclip-runner/src/backends/harness-driver-backend.ts:688
this.#rethrowProtocolIntegrity(error);
throw error;
}
}
steer(input: {
turnId: string;
message: { role: "user"; text: string };
correlationId?: string;
}) {
this.#assertProtocolIntegrity();
if (this.#session.steer === undefined)
throw new Error("steering is unavailable");
return this.#withProtocolIntegrity(() => this.#session.steer!(input));
}
interrupt(input: { turnId?: string; reason?: string }) {
if (this.#session.interrupt === undefined)
throw new Error("interruption is unavailable");
return this.#session.interrupt(input);
}
cancel(input: { reason: string; signal: AbortSignal }) {
if (input.signal.aborted) {
throw (
input.signal.reason ?? new Error("native session cancellation aborted")
);
}
// This flag is the adapter's synchronous publication boundary. Provider
// interruption happens afterward as passive cleanup, so a slow or broken
// transport cannot synthesize or publish new accepted output for the turn.
this.#explicitlyCancelled = true;
const interrupt = this.#session.interrupt;
return {
cleanup:
interrupt === undefined
? Promise.resolve()View on GitHub (pinned to 01ad858492)
Solutions
- Use the backend's cancel() path (AbortSignal-based) instead of turn-level interrupt when interrupt is unsupported
- Upgrade the driver/adapter to one implementing interrupt
- Disable or hide turn-level stop controls for agents that report no interrupt capability
- Feature-detect interrupt support before offering it
Example fix
// before
backend.interrupt({ turnId, reason: 'user-cancel' });
// after
if (!backend.canInterrupt()) {
abortController.abort(); // drives cancel(signal) path
} else {
backend.interrupt({ turnId, reason: 'user-cancel' });
} Defensive patterns
Strategy: try-catch
Validate before calling
if (typeof session.interrupt !== 'function') prepareAbortSignalFallback();
Type guard
const canInterrupt = (s: HarnessSession): s is HarnessSession & { interrupt: NonNullable<HarnessSession['interrupt']> } => typeof s.interrupt === 'function'; Try / catch
try { backend.interrupt({ turnId, reason }); } catch (e) { if (e.message === 'interruption is unavailable') { abortController.abort(); } else throw e; } Prevention
- Use AbortSignal-based cancel as the universal stop path
- Hide turn-level stop controls for drivers without interrupt
- Keep drivers updated to protocol versions with interrupt
When it happens
Trigger: Calling interrupt() on a session whose driver lacks an interrupt implementation; attempting to cancel a turn on a driver that only supports full session cancel via cancel().
Common situations: Stop button in the UI targeting an agent adapter without turn-level interruption; older driver builds predating the interrupt protocol method; drivers that only support process-level cancellation.
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
- native_session_multi_run_unavailable
- steering is unavailable
- native_runtime_request_resolution_unavailable
- native_runtime_request_handoff_unavailable
- native_session_goal_unavailable
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/2e0b4c09b588c948.
Report an issue: GitHub.