{"record":{"id":"a8141a98aee68987","repo":"vercel/ai","slug":"cline-session-has-been-stopped","errorCode":null,"errorMessage":"Cline session has been stopped.","messagePattern":"Cline session has been stopped\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/harness-cline/src/cline-session.ts","lineNumber":575,"sourceCode":"  }\n\n  /*\n   * Drive one turn against the Cline runtime and return the control surface.\n   * Shared by `doPromptTurn` (a fresh user prompt) and `doContinueTurn`\n   * (no prompt — the runtime continues its own thread after a rerun resume).\n   */\n  async function runTurn(turnOpts: {\n    text: string | undefined;\n    model?: string;\n    skills: ReadonlyArray<HarnessV1Skill>;\n    tools: ReadonlyArray<HarnessV1ToolSpec>;\n    instructions?: string;\n    emit: (part: HarnessV1StreamPart) => void;\n    abortSignal?: AbortSignal;\n    responseFormat?: HarnessV1PromptTurnOptions['responseFormat'];\n  }): Promise<HarnessV1PromptControl> {\n    if (stopped) {\n      throw new Error('Cline session has been stopped.');\n    }\n\n    const userTools = turnOpts.tools;\n    const skillsRuntime = createClineSkillsRuntime({\n      skills: turnOpts.skills,\n    });\n    if (\n      turnOpts.responseFormat?.type === 'json' &&\n      turnOpts.responseFormat.schema == null\n    ) {\n      throw new HarnessCapabilityUnsupportedError({\n        message:\n          \"Harness 'cline' requires a JSON schema for structured output.\",\n        harnessId: HARNESS_ID,\n      });\n    }\n    if (\n      turnOpts.responseFormat?.type === 'json' &&","sourceCodeStart":557,"sourceCodeEnd":593,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/harness-cline/src/cline-session.ts#L557-L593","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nawait session.stop();\nawait session.prompt({ text: 'continue' }); // throws\n// after\nawait session.stop();\nconst newSession = await cline.createSession({ ... });\nawait newSession.prompt({ text: 'continue' });","handlingStrategy":"try-catch","validationCode":"const sessionState = sessionRegistry.get(id);\nif (!sessionState || sessionState.stopped) throw new Error(`Session ${id} already stopped; create a new session`);","typeGuard":null,"tryCatchPattern":"try {\n  await session.prompt(turnOpts);\n} catch (e) {\n  if (e instanceof Error && e.message === 'Cline session has been stopped.') {\n    session = await cline.createSession(sessionInit);\n    await session.prompt(turnOpts);\n  } else throw e;\n}","preventionTips":["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."],"tags":["lifecycle","session-state","cline"],"backgroundTag":"session-already-stopped","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}