{"record":{"id":"6e4040ff6616abe9","repo":"paperclipai/paperclip","slug":"steering-is-unavailable-6e4040","errorCode":null,"errorMessage":"Steering is unavailable.","messagePattern":"Steering is unavailable\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ui/src/components/TaskChatThread.tsx","lineNumber":2713,"sourceCode":"              <TaskChatTurnStatusIsland model={tailTurnStatus} />\n            ) : null}\n            <RunnerGoalWidget control={runnerGoal} />\n            <div\n              className=\"relative isolate flex flex-col\"\n              data-testid=\"task-chat-composer-stack\"\n            >\n              {queuedMessageQueue ? (\n                <TaskChatQueuedMessages\n                  queue={queuedMessageQueue}\n                  onEdit={beginQueuedEdit}\n                  onReorder={async (orderedCommentIds, revision) => {\n                    if (!onReorderQueuedComments)\n                      throw new Error(\"Queue reordering is unavailable.\");\n                    await onReorderQueuedComments(orderedCommentIds, revision);\n                  }}\n                  onSteer={async (commentId, revision) => {\n                    if (!onSteerQueuedComment)\n                      throw new Error(\"Steering is unavailable.\");\n                    await onSteerQueuedComment(commentId, revision);\n                  }}\n                  onInterrupt={\n                    onInterruptQueued && queuedMessageQueue.targetRunId\n                      ? async () => {\n                          await onInterruptQueued(\n                            queuedMessageQueue.targetRunId!,\n                          );\n                        }\n                      : undefined\n                  }\n                  onDiscard={async (commentId, revision) => {\n                    if (commentId.startsWith(\"optimistic-\")) {\n                      if (!onCancelQueued)\n                        throw new Error(\"Discard is unavailable.\");\n                      onCancelQueued(commentId);\n                      return;\n                    }","sourceCodeStart":2695,"sourceCodeEnd":2731,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/ui/src/components/TaskChatThread.tsx#L2695-L2731","documentation":"TaskChatThread's queued-message list renders an onSteer callback that forwards a steer request for a queued comment to the parent. When the parent did not supply the onSteerQueuedComment prop, the component throws \"Steering is unavailable.\" instead of silently doing nothing. This is a guard ensuring steer actions are only offered/executed when the parent wiring supports them.","triggerScenarios":"User clicks the steer action on a queued comment in TaskChatThread while the onSteerQueuedComment prop is undefined (not passed by the page embedding TaskChatThread).","commonSituations":"Embedding TaskChatThread in a custom page or older call site that predates the steer feature; a feature flag or conditional render path where the parent omits queue-mutation handlers; UI rendered in a context (e.g. read-only or completed task) where steering handlers are intentionally not wired.","solutions":["Pass the onSteerQueuedComment prop to TaskChatThread at the call site.","Check the embedding page: use the standard task page (which wires steering) or add the wiring yourself.","If steering is intentionally unsupported, hide/disable the steer action instead of rendering it.","Update the custom embed to the current TaskChatThread API, which expects queue mutation handlers."],"exampleFix":"// before\n<TaskChatThread issueId={id} onReorderQueuedComments={reorder} />\n\n// after\n<TaskChatThread\n  issueId={id}\n  onReorderQueuedComments={reorder}\n  onSteerQueuedComment={async (commentId, revision) => {\n    await api.steerQueuedComment(issueId, commentId, revision);\n  }}\n/>","handlingStrategy":"validation","validationCode":"const canSteer = typeof onSteerQueuedComment === \"function\";\nif (!canSteer) hideSteerActions(); // render the queue without steer affordances","typeGuard":"const hasSteer = (p: unknown): p is (id: string, rev: number) => Promise<void> =>\n  typeof p === \"function\";","tryCatchPattern":"try {\n  await onSteer(commentId, revision);\n} catch (e) {\n  if (e instanceof Error && e.message === \"Steering is unavailable.\") {\n    toast(\"Steering is not supported in this view.\");\n  } else throw e;\n}","preventionTips":["Always pass queue mutation handlers when rendering TaskChatThread in editable contexts.","Render steer actions conditionally on the presence of the handler.","Keep custom embeds in sync with the current TaskChatThread prop contract."],"tags":["react","ui","missing-prop","queued-comments"],"backgroundTag":"missing-required-argument","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}