paperclipai/paperclip · error · Error

Steering is unavailable.

Error message

Steering is unavailable.

What it means

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.

Solutions

  1. Pass the onSteerQueuedComment prop to TaskChatThread at the call site.
  2. Check the embedding page: use the standard task page (which wires steering) or add the wiring yourself.
  3. If steering is intentionally unsupported, hide/disable the steer action instead of rendering it.
  4. Update the custom embed to the current TaskChatThread API, which expects queue mutation handlers.

Example fix

// before
<TaskChatThread issueId={id} onReorderQueuedComments={reorder} />

// after
<TaskChatThread
  issueId={id}
  onReorderQueuedComments={reorder}
  onSteerQueuedComment={async (commentId, revision) => {
    await api.steerQueuedComment(issueId, commentId, revision);
  }}
/>
Defensive patterns

Strategy: validation

Validate before calling

const canSteer = typeof onSteerQueuedComment === "function";
if (!canSteer) hideSteerActions(); // render the queue without steer affordances

Type guard

const hasSteer = (p: unknown): p is (id: string, rev: number) => Promise<void> =>
  typeof p === "function";

Try / catch

try {
  await onSteer(commentId, revision);
} catch (e) {
  if (e instanceof Error && e.message === "Steering is unavailable.") {
    toast("Steering is not supported in this view.");
  } else throw e;
}

Prevention

When it happens

Trigger: User clicks the steer action on a queued comment in TaskChatThread while the onSteerQueuedComment prop is undefined (not passed by the page embedding TaskChatThread).

Common situations: 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.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18). Data as JSON: /api/errors/6e4040ff6616abe9. Report an issue: GitHub.

Appendix: source

Thrown at ui/src/components/TaskChatThread.tsx:2980

                <div
                  className="relative isolate flex flex-col"
                  data-testid="task-chat-composer-stack"
                >
                  {queuedMessageQueue && !composerPause ? (
                    <TaskChatQueuedMessages
                      queue={queuedMessageQueue}
                      onEdit={beginQueuedEdit}
                      onReorder={async (orderedCommentIds, revision) => {
                        if (!onReorderQueuedComments)
                          throw new Error("Queue reordering is unavailable.");
                        await onReorderQueuedComments(
                          orderedCommentIds,
                          revision,
                        );
                      }}
                      onSteer={async (commentId, revision) => {
                        if (!onSteerQueuedComment)
                          throw new Error("Steering is unavailable.");
                        await onSteerQueuedComment(commentId, revision);
                      }}
                      onInterrupt={
                        onInterruptQueued && queuedMessageQueue.queueId
                          ? async () => {
                              await onInterruptQueued(
                                queuedMessageQueue.targetRunId,
                              );
                            }
                          : undefined
                      }
                      onDiscard={async (commentId, revision) => {
                        if (commentId.startsWith("optimistic-")) {
                          if (!onCancelQueued)
                            throw new Error("Discard is unavailable.");
                          onCancelQueued(commentId);
                          return;
                        }

View on GitHub (pinned to 3f1d897a7c)