vercel/ai · error
`Harness session ${this.sessionId} has no unfinished turn to
Error message
`Harness session ${this.sessionId} has no unfinished turn to continue.` What it means
Also thrown by `requireContinuableTurn()` from `continueTurn()`, for the 'idle' state: no turn exists to continue. Continuation requires a prior turn that paused or suspended; with turnState 'idle' (no turn started yet, or the previous turn already finished or failed) there is nothing to resume and the library refuses. Start a turn with `promptTurn()` first.
Source
Thrown at packages/harness/src/agent/harness-agent-session.ts:664
throw new Error(
`Harness session ${this.sessionId} has an unfinished turn and must be continued before accepting a new prompt.`,
);
}
private requireContinuableTurn(): void {
if (
this.turnState === 'awaiting-approval' ||
this.turnState === 'awaiting-tool-result' ||
this.turnState === 'suspended'
) {
return;
}
if (this.turnState === 'running') {
throw new Error(
`Harness session ${this.sessionId} already has a turn in progress.`,
);
}
throw new Error(
`Harness session ${this.sessionId} has no unfinished turn to continue.`,
);
}
private markAwaitingApprovalIfActive(): void {
if (this.sessionState === 'active') {
this.clearActivePromptControl();
this.turnState = 'awaiting-approval';
}
}
private markAwaitingToolResultIfActive(): void {
if (this.sessionState === 'active') {
this.clearActivePromptControl();
this.turnState = 'awaiting-tool-result';
}
}
View on GitHub (pinned to 69428b1f8b)
Solutions
- Call `promptTurn()` to start a turn before any continueTurn; only continue turns that are awaiting approval/tool-result or suspended.
- Check `hasUnfinishedTurn()` before continueTurn and fall back to promptTurn (or exit the loop) when it is false.
- After a turn failure, start a new turn with promptTurn rather than continueTurn.
- Fix loop logic so continueTurn is called at most once per suspension, and stop iterating when the turn completes.
Example fix
// before
// previous turn already finished
session.continueTurn({ ... }); // throws: no unfinished turn
// after
if (session.hasUnfinishedTurn()) {
const cont = session.continueTurn({ ... });
await cont.ready;
} else {
const turn = session.promptTurn({ prompt: 'new task', ... });
await turn.ready;
} Defensive patterns
Strategy: validation
Validate before calling
if (!session.hasUnfinishedTurn()) {
throw new NothingToContinueError(); // start with promptTurn instead
} Try / catch
try {
session.continueTurn({ ... });
} catch (error) {
if (error instanceof Error && /has no unfinished turn to continue/.test(error.message)) {
session.promptTurn({ prompt, ... }); // nothing to continue; start fresh
} else {
throw error;
}
} Prevention
- Gate continueTurn behind `hasUnfinishedTurn()`; fall back to promptTurn when idle.
- Use continueTurn at most once per suspension; after completion, start a new prompt.
- After a failed turn, restart with promptTurn — continueTurn cannot revive an idle session.
- In slice loops, exit when the turn finishes instead of continuing unconditionally.
When it happens
Trigger: Calling `continueTurn()` on a freshly created/resumed session before any promptTurn; calling continueTurn after the previous turn already completed or failed (state reset to idle by finishTrackedTurn); calling continueTurn twice after a suspension — the first continue starts a running turn, and once it finishes, a second continue finds idle.
Common situations: Orchestration loops that unconditionally continueTurn each iteration without checking whether the prior turn finished; retrying a failed turn with continueTurn instead of promptTurn; resuming a session from persisted state where the stored continuation was already consumed; off-by-one in slice-based schedulers that continue after the final slice.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Harness session ${this.sessionId} has no unfinished turn to
- `Harness session ${this.sessionId} already has a turn in pro
- `Harness session ${this.sessionId} has an unfinished turn an
- Invalid argument for parameter requests: requests must not b
- Invalid argument for parameter requests: request IDs must no
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/1a661006e611e325.
Report an issue: GitHub.