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
- Do not call runTurn on a session after stop(); create a new session (or resume state) for further turns.
- Guard turn submission behind a check of your own lifecycle state so turns are not issued after stop is initiated.
- 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
- Track a `stopped` flag per session in your app and refuse new turns once stop was initiated.
- Centralize session lifecycle (stop/suspend) in one place instead of scattering stop calls across handlers.
- Clean up cached session references in abort/dispose handlers so stale handles are not reused.
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
- Pi has no active runtime session to steer.
- Invalid argument for parameter requests: requests must not b
- Invalid argument for parameter requests: request IDs must no
- Invalid argument for parameter requests: request IDs must be
- Invalid argument for parameter batch: batch must be a suppor
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/a8141a98aee68987.
Report an issue: GitHub.