vercel/ai · error

OpenCode turn settled without a correlated assistant respons

Error message

OpenCode turn settled without a correlated assistant response.

What it means

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.

Source

Thrown at packages/harness-opencode/src/bridge/index.ts:789

  const settlement = await turnSettled.promise;
  eventsAbort.abort();
  await eventLoop.catch(() => {});
  await userMessageLoop.catch(() => {});
  if (settlement === 'stream-ended') {
    throw new Error('OpenCode event stream ended before the turn settled.');
  }
  if (terminalError) throw new Error(terminalError);
  if (!sawFinishStep) {
    const emittedFallback = await emitContextFallback({
      client,
      sessionId,
      assistantBaseline,
      state,
      emit,
      emitContent: !sawContent,
    }).catch(() => false);
    if (!emittedFallback) {
      throw new Error(
        'OpenCode turn settled without a correlated assistant response.',
      );
    }
  }
  const finalSessionTokens =
    (await readSessionTokens({ client, sessionId }).catch(() => undefined)) ??
    latestSessionTokens;
  if (initialSessionTokens && finalSessionTokens) {
    return mapUsage(
      subtractSessionTokens({
        before: initialSessionTokens,
        after: finalSessionTokens,
      }),
    );
  }
  return stepUsage;
}

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Check your OpenCode version matches the harness bridge expectations (event types like message.updated/step events).
  2. Ensure emitContextFallback preconditions hold: the session must persist assistant messages readable via the client after the turn.
  3. Log the translated events emitted during the turn to see which events were received/filtered.
  4. Retry the turn; a race between subscription and the first assistant event can cause missed correlation.

Example fix

// before: mismatched opencode version emits old event names
"opencode": "0.3.1"
// after: use a version whose event stream matches the bridge
"opencode": ">=0.4.0"
Defensive patterns

Strategy: try-catch

Validate before calling

// smoke-test the event pipeline before real turns
const ok = await bridge.run({ prompt: 'ping', expect: /./ }).then(() => true).catch(() => false);
if (!ok) throw new Error('OpenCode event correlation smoke test failed — check versions');

Type guard

function isUn correlatedAssistantError(e: unknown): e is Error {
  return e instanceof Error && e.message === 'OpenCode turn settled without a correlated assistant response.';
}

Try / catch

try {
  await bridge.runTurn(...);
} catch (e) {
  if (isUncorrelatedAssistantError(e)) {
    console.error('No finish-step or fallback output — check OpenCode version/event shapes');
    // upgrade OpenCode, then retry
  } else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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