vercel/ai · error · Error

Cline session has been stopped.

Error message

Cline session has been stopped.

What it means

runTurn on a Cline session checks the session's `stopped` flag before doing any work. Once doStop() has been called (or the session was otherwise stopped), any attempt to run a new prompt turn throws this plain Error. A stopped Cline session is terminal: it has been removed from the parked-session registry and its runtime disposed.

Source

Thrown at packages/harness-cline/src/cline-session.ts:575

  }

  /*
   * Drive one turn against the Cline runtime and return the control surface.
   * Shared by `doPromptTurn` (a fresh user prompt) and `doContinueTurn`
   * (no prompt — the runtime continues its own thread after a rerun resume).
   */
  async function runTurn(turnOpts: {
    text: string | undefined;
    model?: string;
    skills: ReadonlyArray<HarnessV1Skill>;
    tools: ReadonlyArray<HarnessV1ToolSpec>;
    instructions?: string;
    emit: (part: HarnessV1StreamPart) => void;
    abortSignal?: AbortSignal;
    responseFormat?: HarnessV1PromptTurnOptions['responseFormat'];
  }): Promise<HarnessV1PromptControl> {
    if (stopped) {
      throw new Error('Cline session has been stopped.');
    }

    const userTools = turnOpts.tools;
    const skillsRuntime = createClineSkillsRuntime({
      skills: turnOpts.skills,
    });
    if (
      turnOpts.responseFormat?.type === 'json' &&
      turnOpts.responseFormat.schema == null
    ) {
      throw new HarnessCapabilityUnsupportedError({
        message:
          "Harness 'cline' requires a JSON schema for structured output.",
        harnessId: HARNESS_ID,
      });
    }
    if (
      turnOpts.responseFormat?.type === 'json' &&

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Do not call runTurn on a session after stop(); create a new session (or resume state) for further turns.
  2. Guard turn submission behind a check of your own lifecycle state so turns are not issued after stop is initiated.
  3. If you need to pause and later continue, investigate doSuspendTurn/continueTurn instead of stop, since stop is irreversible.

Example fix

// before
await session.stop();
await session.prompt({ text: 'continue' }); // throws
// after
await session.stop();
const newSession = await cline.createSession({ ... });
await newSession.prompt({ text: 'continue' });
Defensive patterns

Strategy: try-catch

Validate before calling

const sessionState = sessionRegistry.get(id);
if (!sessionState || sessionState.stopped) throw new Error(`Session ${id} already stopped; create a new session`);

Try / catch

try {
  await session.prompt(turnOpts);
} catch (e) {
  if (e instanceof Error && e.message === 'Cline session has been stopped.') {
    session = await cline.createSession(sessionInit);
    await session.prompt(turnOpts);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling session.prompt/runTurn (the internal runTurn via sessionImpl) after await session.stop(), or racing a turn against a stop call so the turn starts after `stopped` was set to true.

Common situations: UI disposes a chat while a queued message is submitted concurrently; a timeout/abort handler calls stop while the app still issues another turn; reusing a cached session object that was stopped in a previous request lifecycle.

Related errors


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