{"record":{"id":"d0eab93aa33de49e","repo":"vercel/ai","slug":"opencode-turn-settled-without-a-correlated-assista","errorCode":null,"errorMessage":"OpenCode turn settled without a correlated assistant response.","messagePattern":"OpenCode turn settled without a correlated assistant response\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/harness-opencode/src/bridge/index.ts","lineNumber":789,"sourceCode":"  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;\n  if (initialSessionTokens && finalSessionTokens) {\n    return mapUsage(\n      subtractSessionTokens({\n        before: initialSessionTokens,\n        after: finalSessionTokens,\n      }),\n    );\n  }\n  return stepUsage;\n}\n","sourceCodeStart":771,"sourceCodeEnd":807,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/harness-opencode/src/bridge/index.ts#L771-L807","documentation":"runPrompt tracks whether it saw a finish-step event; if the turn settled without one, it tries emitContextFallback, which reconstructs the assistant response from the session's message snapshots. If that fallback also fails, this error is thrown. It means the bridge could not correlate any assistant output to this turn despite the turn settling normally.","triggerScenarios":"The turn settles (busy->idle or structured output path) but no finish-step was emitted and emitContextFallback returns false — e.g. the server produced no assistant message, events for the assistant message were filtered or missed before the baseline snapshot, or the session has no retrievable messages.","commonSituations":"OpenCode event naming/shape drift so events are not recognized as content; events consumed before the subscription baseline; the assistant produced only an error with no message persisted; custom/older OpenCode servers that skip step events.","solutions":["Check your OpenCode version matches the harness bridge expectations (event types like message.updated/step events).","Ensure emitContextFallback preconditions hold: the session must persist assistant messages readable via the client after the turn.","Log the translated events emitted during the turn to see which events were received/filtered.","Retry the turn; a race between subscription and the first assistant event can cause missed correlation."],"exampleFix":"// before: mismatched opencode version emits old event names\n\"opencode\": \"0.3.1\"\n// after: use a version whose event stream matches the bridge\n\"opencode\": \">=0.4.0\"","handlingStrategy":"try-catch","validationCode":"// smoke-test the event pipeline before real turns\nconst ok = await bridge.run({ prompt: 'ping', expect: /./ }).then(() => true).catch(() => false);\nif (!ok) throw new Error('OpenCode event correlation smoke test failed — check versions');","typeGuard":"function isUn correlatedAssistantError(e: unknown): e is Error {\n  return e instanceof Error && e.message === 'OpenCode turn settled without a correlated assistant response.';\n}","tryCatchPattern":"try {\n  await bridge.runTurn(...);\n} catch (e) {\n  if (isUncorrelatedAssistantError(e)) {\n    console.error('No finish-step or fallback output — check OpenCode version/event shapes');\n    // upgrade OpenCode, then retry\n  } else throw e;\n}","preventionTips":["Keep OpenCode server and bridge versions in lockstep.","Add a startup smoke-test turn that asserts a finish-step arrives.","Log translated events during development to catch event-shape drift early.","Ensure the session persists assistant messages so the snapshot fallback can work."],"tags":["opencode","event-stream","correlation","version-mismatch"],"backgroundTag":"missing-assistant-response","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}