Significant-Gravitas/AutoGPT · error · HTTPException

Chat service degraded, retry shortly

Error message

Chat service degraded, retry shortly

What it means

HTTP 503 with header Retry-After: 30 from POST /chat/stream (routes.py:1411). Before enqueueing a turn, the endpoint checks is_turn_in_flight(session_id) against the stream registry backed by Redis. StreamRegistryUnavailable means Redis could not answer. As the source comment explains, this pre-flight step runs before check_rate_limit, so the branch maps the failure to a polished 503 + Retry-After instead of a raw 500.

Source

Thrown at autogpt_platform/backend/backend/api/features/chat/routes.py:1411

    # Session-anchored tenancy: the ChatSession row is the authoritative
    # org/team for every turn in it — a user whose active header org
    # differs still charges/attributes turns to the session's org.
    # Untagged legacy sessions fall back to the request context.
    turn_org_id = session.organization_id or ctx.org_id
    turn_team_id = session.team_id if session.organization_id else ctx.team_id

    try:
        turn_in_flight = (
            request.is_user_message
            and request.message
            and await is_turn_in_flight(session_id)
        )
    except StreamRegistryUnavailable as exc:
        # Same fail-closed mapping as the RateLimitUnavailable branch below:
        # the pre-flight chain runs is_turn_in_flight BEFORE check_rate_limit,
        # so a Redis brown-out at this step would otherwise surface as a raw
        # 500 instead of the polished 503 + Retry-After.
        raise HTTPException(
            status_code=503,
            detail="Chat service degraded, retry shortly",
            headers={"Retry-After": "30"},
        ) from exc

    if turn_in_flight:
        try:
            await queue_pending_for_http(
                session_id=session_id,
                user_id=user_id,
                message=request.message,
                context=request.context,
                file_ids=request.file_ids,
            )
            return _empty_ui_message_stream_response()
        except HTTPException as exc:
            if exc.status_code != 409:
                raise

View on GitHub (pinned to 9c8bb5550f)

Solutions

  1. Retry after ~30 seconds honoring the Retry-After header; the condition is transient.
  2. Ops: restore Redis (check docker compose / redis health); chat streaming depends on it for turn-in-flight tracking.
  3. Client-side: implement exponential backoff capped by Retry-After for 503s on /chat/stream and show a 'service degraded' toast instead of an error dump.
  4. If persistent, verify REDIS connection config and network policy between backend and Redis.

Example fix

// before
const res = await fetch('/chat/stream', ...);
if (!res.ok) throw new Error(res.status); // raw 503

// after — honor Retry-After on 503
if (res.status === 503) {
  const wait = Number(res.headers.get('Retry-After') ?? 30) * 1000;
  await sleep(wait);
  return retryOnce();
}
Defensive patterns

Strategy: retry

Try / catch

try { await post('/chat/stream', body); } catch (e) {
  if (e.status === 503) {
    const wait = Number(e.headers?.['retry-after'] ?? 30) * 1000;
    await sleep(wait);
    return retryWithBackoff(postStream, body, {max: 3});
  }
  throw e;
}

Prevention

When it happens

Trigger: POST /chat/stream with is_user_message and a non-empty message while Redis (stream registry) is unavailable — raise of StreamRegistryUnavailable from is_turn_in_flight(session_id).

Common situations: Redis restart/failover during active chat traffic; local dev without Redis up; brown-out under connection-pool exhaustion. Users mid-conversation suddenly cannot send any message.

Related errors


AI-assisted analysis of Significant-Gravitas/AutoGPT@9c8bb5550f (2026-08-14). Data as JSON: /api/errors/a42115d09d1c1770. Report an issue: GitHub.