vercel/ai · error

Pi has no active runtime session to steer.

Error message

Pi has no active runtime session to steer.

What it means

submitUserMessage on the returned prompt control requires a live Pi runtime session (`piSession`). The adapter throws this error when steering is requested before any Pi session has been created/activated. It is a lifecycle-state guard, not a network failure.

Source

Thrown at packages/harness-pi/src/pi-session.ts:896

         * (so the model reads it), and Pi echoes that text back — without this
         * the consumer-facing result would be the serialized string instead of
         * the original object.
         */
        translatorState?.hostToolResults.set(args.toolCallId, args.output);
        pending.resolve(args.output);
      },
      async submitToolApproval(args) {
        const pending = pendingToolApprovals.get(args.approvalId);
        if (!pending) return;
        pendingToolApprovals.delete(args.approvalId);
        pending.resolve({
          approved: args.approved,
          reason: args.reason,
        });
      },
      async submitUserMessage(text) {
        if (piSession == null) {
          throw new Error('Pi has no active runtime session to steer.');
        }
        await piSession.steer(text);
      },
      done: input.done,
    };
  }

  async function requestBuiltinToolApproval(args: {
    toolCallId: string;
    nativeName: (typeof PI_NATIVE_BUILTIN_NAMES)[number];
  }): Promise<{ approved: boolean; reason?: string }> {
    if (
      !piBuiltinToolRequiresApproval({
        permissionMode,
        kind: PI_NATIVE_TOOL_KINDS[args.nativeName],
      })
    ) {
      return { approved: true };

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Start a turn (prompt/continue) so the Pi runtime session is active before steering
  2. Check session lifecycle state before calling submitUserMessage
  3. Re-create or re-resume the session if the runtime was stopped

Example fix

// before
const ctrl = await session.submitUserMessage('go left'); // no active turn yet
// after
await session.prompt({ prompt: 'start' }); // establishes Pi session
const ctrl = await session.submitUserMessage('go left');
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await session.submitUserMessage(text);
} catch (e) {
  if (e instanceof Error && e.message.includes('no active runtime session')) {
    await session.prompt({ prompt: text }); // start a turn instead of steering
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling `submitUserMessage` (steer) on a session/resumedSession handle before the first turn has started a Pi runtime session, or after the underlying Pi session was torn down without being re-established.

Common situations: Steering a freshly created Pi session before calling prompt; racing steer against session teardown; resuming a session whose Pi runtime was never started in this process.

Related errors


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/5ae13960a8a59466. Report an issue: GitHub.