{"record":{"id":"0d70e96d453a55c9","repo":"vercel/ai","slug":"terminalerror","errorCode":null,"errorMessage":"${terminalError}","messagePattern":"\\$\\{terminalError\\}","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"packages/harness-opencode/src/bridge/index.ts","lineNumber":778,"sourceCode":"    client,\n    sessionId,\n    start,\n  });\n  if (prompted.error) {\n    eventsAbort.abort();\n    turn.experimental_userMessages.close(\n      new Error(`OpenCode prompt failed: ${formatError(prompted.error)}`),\n    );\n    throw new Error(`OpenCode prompt failed: ${formatError(prompted.error)}`);\n  }\n  const settlement = await turnSettled.promise;\n  eventsAbort.abort();\n  await eventLoop.catch(() => {});\n  await userMessageLoop.catch(() => {});\n  if (settlement === 'stream-ended') {\n    throw new Error('OpenCode event stream ended before the turn settled.');\n  }\n  if (terminalError) throw new Error(terminalError);\n  if (!sawFinishStep) {\n    const emittedFallback = await emitContextFallback({\n      client,\n      sessionId,\n      assistantBaseline,\n      state,\n      emit,\n      emitContent: !sawContent,\n    }).catch(() => false);\n    if (!emittedFallback) {\n      throw new Error(\n        'OpenCode turn settled without a correlated assistant response.',\n      );\n    }\n  }\n  const finalSessionTokens =\n    (await readSessionTokens({ client, sessionId }).catch(() => undefined)) ??\n    latestSessionTokens;","sourceCodeStart":760,"sourceCodeEnd":796,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/harness-opencode/src/bridge/index.ts#L760-L796","documentation":"When the OpenCode event stream emits a session.error event, runPrompt records the formatted error in terminalError and rethrows it as a plain Error after the turn settles. This is the OpenCode server reporting a terminal failure for the turn (e.g. the underlying model/provider errored). The message is whatever OpenCode reported.","triggerScenarios":"During a turn, consumeEvents receives event.type === 'session.error' (or terminal failure from the server), e.g. the LLM provider returned an error, the model quota was exhausted, or a tool execution caused a fatal server error.","commonSituations":"Invalid or rate-limited LLM provider API key on the OpenCode server; provider outage mid-turn; model id not available for the configured provider; OpenCode internal error while executing tools.","solutions":["Read terminalError content in the message — it contains OpenCode's formatted provider/server error — and fix that underlying cause.","Verify the LLM provider API keys and quotas configured on the OpenCode server.","Check the model id in your start options is valid for the provider.","Retry the turn after resolving provider-side issues."],"exampleFix":"// before: expired provider key on opencode server\nexport ANTHROPIC_API_KEY=sk-expired\n// after\nexport ANTHROPIC_API_KEY=sk-valid\nopencode auth login","handlingStrategy":"try-catch","validationCode":"// preflight provider auth on the OpenCode server\nconst models = await fetch(`${base}/config/provider`).then(r => r.json());\nif (!models?.length) throw new Error('No provider configured on OpenCode server');","typeGuard":"function isTerminalSessionError(e: unknown): e is Error {\n  return e instanceof Error && !e.message.startsWith('OpenCode ') && e.message.length > 0 && /error|failed|quota|limit/i.test(e.message);\n}","tryCatchPattern":"try {\n  await bridge.runTurn(...);\n} catch (e) {\n  if (e instanceof Error && /quota|rate.?limit/i.test(e.message)) {\n    await sleep(60_000); // back off provider rate limits\n  } else if (e instanceof Error && /api.?key|auth/i.test(e.message)) {\n    console.error('Fix provider credentials on the OpenCode server');\n  } else throw e;\n}","preventionTips":["Validate provider API keys and quotas before long agent runs.","Use valid model ids for the configured provider.","Monitor provider status pages during critical runs.","Set retry/backoff policies for rate-limit errors."],"tags":["opencode","provider-error","llm","turn"],"backgroundTag":"llm-provider-error","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}