paperclipai/paperclip · error
steering is unavailable
Error message
steering is unavailable
What it means
steer forwards a mid-turn user message to the underlying HarnessSession's optional steer capability. When the session driver does not implement steer (this.#session.steer === undefined), the backend throws "steering is unavailable" because the driver cannot inject messages into an in-flight turn. The call is wrapped with protocol-integrity checks on entry and exit.
Source
Thrown at packages/paperclip-runner/src/backends/harness-driver-backend.ts:682
this.#assertProtocolIntegrity();
try {
const started = await this.#session.startTurn(input);
this.#assertProtocolIntegrity();
return started;
} catch (error) {
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.View on GitHub (pinned to 01ad858492)
Solutions
- Verify the driver implements steer before enabling steering in the UI/CLI for that agent type
- Upgrade the adapter/driver to a version with steer support
- Queue the message and deliver it as the next turn's user message instead of steering
- Feature-detect: if (!session.steer) fall back to interrupt-then-send
Example fix
// before
await backend.steer({ turnId, message });
// after
if (!backend.canSteer()) {
await backend.interrupt({ reason: 'pending-steer' });
await backend.send({ message });
} else {
await backend.steer({ turnId, message });
} Defensive patterns
Strategy: try-catch
Validate before calling
if (typeof session.steer !== 'function') throw new Error('steering not supported by this driver'); Type guard
const canSteer = (s: HarnessSession): s is HarnessSession & { steer: NonNullable<HarnessSession['steer']> } => typeof s.steer === 'function'; Try / catch
try { await backend.steer({ turnId, message }); } catch (e) { if (e.message === 'steering is unavailable') { queueForNextTurn(message); } else throw e; } Prevention
- Gate steering UI on driver capability
- Upgrade adapters that lack steer support
- Fall back to interrupt + resend when steering is absent
When it happens
Trigger: Calling steer() while a turn is running on a session whose driver lacks a steer implementation; steering a driver/adapter that never supported mid-turn steering (session.steer undefined).
Common situations: Using an agent adapter (e.g., a non-interactive CLI driver) that cannot accept input mid-run; steering before upgrading to a driver version with steer support; UI sending a steer action for an agent type that only accepts turn-boundary messages.
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
- native_session_goal_unavailable
- native_session_attach_binding_mismatch
- interruption is unavailable
- native_runtime_request_resolution_unavailable
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/0a0c2be89d81a251.
Report an issue: GitHub.