vercel/ai · error · Error

${harnessId} cannot start a new ACP prompt while a turn is i

Error message

${harnessId} cannot start a new ACP prompt while a turn is in flight.

What it means

The ACP harness serializes one turn per session: when doPromptTurn's start callback fires and a turn is already in flight (turnInFlight=true), it refuses to send another 'start' message over the channel. ACP sessions process a single prompt at a time, so concurrent prompts on the same session are rejected.

Source

Thrown at packages/harness-acp/src/v1/acp-v1-harness.ts:1457

        mcpServers,
        debug,
        authenticationProfile,
        sessionMeta,
        instructionMapping,
        responseFormat: options.responseFormat,
        outputSchemaMapping,
        model,
        modelMapping,
      });
      const nextInstructionsFingerprint = fingerprintValue({
        value: options.instructions ?? null,
      });
      const control = wireTurn({
        emit: options.emit,
        abortSignal: options.abortSignal,
        start: () => {
          if (turnInFlight) {
            throw new Error(
              `${harnessId} cannot start a new ACP prompt while a turn is in flight.`,
            );
          }
          turnInFlight = true;
          channel.send({
            type: 'start',
            prompt:
              instructionsFingerprint !== nextInstructionsFingerprint &&
              (instructionMapping == null || initialGuidanceApplied)
                ? prependACPInstructionGuidance({
                    prompt,
                    instructions: options.instructions,
                  })
                : prompt,
            ...(instructionMapping == null
              ? {}
              : {
                  instructionMapping,

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Await the previous promptTurn completion (or its done/error event) before starting a new turn on the same session.
  2. Gate prompt submissions behind a per-session busy flag/mutex so only one turn is ever in flight.
  3. Queue additional prompts and dispatch them sequentially after the current turn finishes.
  4. Create a separate session if you genuinely need parallel turns.

Example fix

// before
session.promptTurn({ prompt });
session.promptTurn({ prompt2 }); // throws: turn in flight
// after
await session.promptTurn({ prompt });
await session.promptTurn({ prompt2 });
Defensive patterns

Strategy: validation

Validate before calling

let busy = false;
async function safePrompt(session, opts) {
  if (busy) throw new Error('turn already in flight');
  busy = true;
  try { return await session.promptTurn(opts); } finally { busy = false; }
}

Try / catch

try {
  await session.promptTurn({ prompt });
} catch (e) {
  if (e instanceof Error && e.message.includes('while a turn is in flight')) {
    await enqueuePrompt(prompt); // retry after current turn completes
  } else throw e;
}

Prevention

When it happens

Trigger: Calling promptTurn on the same session while a previous turn has not completed (no done event yet), including calling promptTurn again before awaiting the prior turn's completion or firing it from a concurrent async task.

Common situations: Race conditions where two parts of an app both send prompts to one session; not awaiting the previous promptTurn promise; UI retry logic double-firing a submit; a long-running turn still streaming when a follow-up prompt is issued.

Related errors


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