{"record":{"id":"0a0c2be89d81a251","repo":"paperclipai/paperclip","slug":"steering-is-unavailable","errorCode":null,"errorMessage":"steering is unavailable","messagePattern":"steering is unavailable","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/backends/harness-driver-backend.ts","lineNumber":687,"sourceCode":"    this.#assertProtocolIntegrity();\n    try {\n      const started = await this.#session.startTurn(input);\n      this.#assertProtocolIntegrity();\n      return started;\n    } catch (error) {\n      this.#rethrowProtocolIntegrity(error);\n      throw error;\n    }\n  }\n\n  steer(input: {\n    turnId: string;\n    message: { role: \"user\"; text: string };\n    correlationId?: string;\n  }) {\n    this.#assertProtocolIntegrity();\n    if (!this.#steeringSupported || this.#session.steer === undefined)\n      throw new Error(\"steering is unavailable\");\n    return this.#withProtocolIntegrity(() => this.#session.steer!(input));\n  }\n\n  interrupt(input: { turnId?: string; reason?: string }) {\n    if (this.#session.interrupt === undefined)\n      throw new Error(\"interruption is unavailable\");\n    return this.#session.interrupt(input);\n  }\n\n  cancel(input: { reason: string; signal: AbortSignal }) {\n    if (input.signal.aborted) {\n      throw (\n        input.signal.reason ?? new Error(\"native session cancellation aborted\")\n      );\n    }\n    // This flag is the adapter's synchronous publication boundary. Provider\n    // interruption happens afterward as passive cleanup, so a slow or broken\n    // transport cannot synthesize or publish new accepted output for the turn.","sourceCodeStart":669,"sourceCodeEnd":705,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/packages/paperclip-runner/src/backends/harness-driver-backend.ts#L669-L705","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\nawait backend.steer({ turnId, message });\n// after\nif (!backend.canSteer()) {\n  await backend.interrupt({ reason: 'pending-steer' });\n  await backend.send({ message });\n} else {\n  await backend.steer({ turnId, message });\n}","handlingStrategy":"try-catch","validationCode":"if (typeof session.steer !== 'function') throw new Error('steering not supported by this driver');","typeGuard":"const canSteer = (s: HarnessSession): s is HarnessSession & { steer: NonNullable<HarnessSession['steer']> } => typeof s.steer === 'function';","tryCatchPattern":"try { await backend.steer({ turnId, message }); } catch (e) { if (e.message === 'steering is unavailable') { queueForNextTurn(message); } else throw e; }","preventionTips":["Gate steering UI on driver capability","Upgrade adapters that lack steer support","Fall back to interrupt + resend when steering is absent"],"tags":["steering","capability-missing","session"],"backgroundTag":"unsupported-operation","analyzedSha":"3f1d897a7c018d76563a21c6e39c3c9b03933622","analyzedAt":"2026-09-18T08:03:59.046Z","contentChangedAt":"2026-09-18T08:03:59.046Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}