Significant-Gravitas/AutoGPT · warning · HTTPException
Session has no active turn. Start a new turn with POST /stre
Error message
Session has no active turn. Start a new turn with POST /stream.
What it means
HTTP 409 from the queue-pending endpoint (routes.py:1732). The endpoint exists ONLY to attach a follow-up message to a currently active turn. It checks is_turn_in_flight(session_id); when false there is nothing to queue onto, so it returns 409 with the corrective action: 'Start a new turn with POST /stream.'
Source
Thrown at autogpt_platform/backend/backend/api/features/chat/routes.py:1732
async def queue_pending_message(
session_id: str,
request: QueuePendingMessageRequest,
user_id: str = Security(auth.get_user_id),
):
"""Queue a follow-up message while the session has an active turn."""
session = await _validate_and_get_session(session_id, user_id)
if session.metadata.llm_auth_provider == "codex":
await enforce_codex_access_http(user_id)
try:
turn_in_flight = await is_turn_in_flight(session_id)
except StreamRegistryUnavailable as exc:
raise HTTPException(
status_code=503,
detail="Chat service degraded, retry shortly",
headers={"Retry-After": "30"},
) from exc
if not turn_in_flight:
raise HTTPException(
status_code=409,
detail="Session has no active turn. Start a new turn with POST /stream.",
)
return await queue_pending_for_http(
session_id=session_id,
user_id=user_id,
message=request.message,
context=request.context,
file_ids=request.file_ids,
)
@router.get(
"/sessions/{session_id}/messages/pending",
response_model=PeekPendingMessagesResponse,
responses={
404: {"description": "Session not found or access denied"},
},View on GitHub (pinned to 9c8bb5550f)
Solutions
- Send the message via POST /chat/stream instead — that starts a new turn.
- Client-side: on 409 from queue-pending, transparently fall back to the stream endpoint so the user's message is never lost.
- Track turn lifecycle (completion events) and route messages accordingly: active turn -> queue-pending, otherwise -> stream.
Example fix
// before
await post(`/chat/sessions/${id}/queue`, {message}); // 409 when turn done
// after — fall back to starting a new turn
try {
await post(`/chat/sessions/${id}/queue`, {message});
} catch (e) {
if (e.status === 409) await post('/chat/stream', {session_id: id, message});
else throw e;
} Defensive patterns
Strategy: fallback
Validate before calling
// track turn lifecycle so you pick the right endpoint up front
const inFlight = await isTurnInFlight(sessionId);
await (inFlight
? post(`/chat/sessions/${id}/queue`, {message})
: post('/chat/stream', {session_id: id, message})); Try / catch
try { await post(`/chat/sessions/${id}/queue`, {message}); } catch (e) {
if (e.status === 409) return post('/chat/stream', {session_id: id, message}); // turn finished; start a new one
throw e;
} Prevention
- On 409 from queue-pending, transparently fall back to POST /stream so the message is never lost
- Subscribe to turn-completion events to keep client turn-state fresh
- Treat queue-pending as attach-only; the stream endpoint is the source of truth for new turns
When it happens
Trigger: Calling queue-pending after the active turn already completed (or before any turn started) — classic race where the turn finishes between the client seeing 'in flight' and the queue-pending POST landing.
Common situations: User types a follow-up right as the agent finishes; client's turn-state subscription lags; retry of a queued message after completion; calling the endpoint on a brand-new session.
Related errors
- Chat service degraded, retry shortly
- You've reached your {window} usage limit. Resets in {time_st
- Rate limit service degraded, retry shortly
- You've reached the limit of {resolved} active tasks (running
- Rate limit reset is not available.
AI-assisted analysis of Significant-Gravitas/AutoGPT@9c8bb5550f (2026-08-14).
Data as JSON: /api/errors/a919e8e49b79353f.
Report an issue: GitHub.