vercel/ai · error · Error

no active turn

Error message

no active turn

What it means

Host tools are LangChain tool wrappers that emit a `tool-call` event and block waiting for the host's `tool-result` via the currently active `BridgeTurn`. If the tool body runs when `currentTurn` is undefined, there is no turn to route the call through, so the bridge throws. This is an internal lifecycle inconsistency: tools should only execute inside a turn.

Source

Thrown at packages/harness-deepagents/src/bridge/index.ts:191

const responseFormatMiddleware = createMiddleware({
  name: 'HarnessResponseFormat',
  wrapModelCall(request, handler) {
    return handler({
      ...request,
      ...(currentResponseFormat == null
        ? {}
        : { responseFormat: currentResponseFormat }),
    });
  },
});

// Host tools become LangChain tools that emit a `tool-call` and block on the host's `tool-result`.
function buildHostTools(toolSchemas: StartMessage['tools']) {
  return (toolSchemas ?? []).map(schema =>
    tool(
      async (input: Record<string, unknown>) => {
        const turn = currentTurn;
        if (!turn) throw new Error('no active turn');
        const toolCallId = `${schema.name}-${randomUUID()}`;
        turn.emit({
          type: 'tool-call',
          toolCallId,
          toolName: schema.name,
          input: JSON.stringify(input),
          providerExecuted: false,
        } as BridgeEvent);
        const { output } = await turn.requestToolResult(toolCallId);
        return typeof output === 'string' ? output : JSON.stringify(output);
      },
      {
        name: schema.name,
        description: schema.description ?? '',
        schema: jsonSchemaToZodObject(schema.inputSchema),
      },
    ),
  );

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Ensure tool invocations originate from within an active harness turn; do not invoke host tools from background tasks or after the turn resolves.
  2. Check for aborted turns: aborting a turn clears context, so in-flight tool calls should be cancelled via the turn's abort signal.
  3. If reproducible, report as a bridge bug — `currentTurn` should be set whenever the agent can execute tools.
  4. Retry the turn; transient races between turn teardown and tool completion typically resolve on a fresh turn.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await runTurn(start);
} catch (error) {
  if (error instanceof Error && error.message === 'no active turn') {
    // discard stale tool call; start a fresh turn
  }
  throw error;
}

Prevention

When it happens

Trigger: A host tool callback executes outside `runTurn`'s window — e.g. a stale agent/tool invoked after a turn completed or aborted, or tools invoked asynchronously after the turn cleared `currentTurn`.

Common situations: An async tool continuation racing with turn teardown; an aborted turn where the model's pending tool call still resolves; reusing a cached agent instance from a previous bridge turn in a background task.

Related errors


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