abi/screenshot-to-code · error · TimeoutError
Request timed out
Error message
Request timed out
What it means
Raised when asyncio.TimeoutError escapes the try block in _run_prediction and is converted to the builtin TimeoutError. In practice this is the socket-level timeout path (httpx default timeouts) rather than the poll-budget exhaustion, which raises TimeoutError("Inference timed out") directly and passes through the (TimeoutError, ValueError) re-raise untouched. Note the bare TimeoutError("Request timed out") message distinguishes the two.
Source
Thrown at backend/image_generation/replicate.py:97
headers = _build_headers(api_token)
async with httpx.AsyncClient() as client:
try:
response = await client.post(endpoint_url, headers=headers, json=payload)
response.raise_for_status()
response_json = response.json()
if not isinstance(response_json, dict):
raise ValueError("Invalid prediction creation response.")
prediction_id = _extract_prediction_id(response_json)
final_response = await _poll_prediction(client, prediction_id, headers)
return final_response.get("output")
except httpx.HTTPStatusError as exc:
raise ValueError(f"HTTP error occurred: {exc}") from exc
except httpx.RequestError as exc:
raise ValueError(f"An error occurred while requesting: {exc}") from exc
except asyncio.TimeoutError as exc:
raise TimeoutError("Request timed out") from exc
except (TimeoutError, ValueError):
raise
except Exception as exc:
raise ValueError(f"An unexpected error occurred: {exc}") from exc
def _extract_output_url(result: Any, context: str) -> str:
if isinstance(result, str):
return result
if isinstance(result, dict):
url = cast(Any, result.get("url"))
if isinstance(url, str) and url:
return url
if isinstance(result, list) and len(result) > 0:
first = cast(Any, result[0])
if isinstance(first, str) and first:View on GitHub (pinned to d026163f58)
Solutions
- Distinguish from "Inference timed out": this one is a single-request timeout, not poll-budget exhaustion.
- Pass an explicit larger timeout when constructing httpx.AsyncClient (e.g. httpx.Timeout(60.0)).
- Retry the operation — single-request timeouts are typically transient.
- Avoid blocking the event loop with sync work during generation.
Example fix
# before async with httpx.AsyncClient() as client: # after async with httpx.AsyncClient(timeout=httpx.Timeout(60.0, connect=10.0)) as client:
Defensive patterns
Strategy: retry
Try / catch
try:
output = await call_replicate_model(model, input, token)
except TimeoutError as e:
if str(e) == "Request timed out":
# single-request timeout: safe to retry immediately
output = await call_replicate_model(model, input, token)
raise Prevention
- Give the AsyncClient an explicit generous timeout instead of relying on httpx defaults
- Distinguish "Request timed out" (one round-trip) from "Inference timed out" (poll budget)
- Keep CPU-heavy sync work off the event loop during generation
When it happens
Trigger: An httpx operation exceeding its default timeout during the creation POST or a polling GET and surfacing as asyncio.TimeoutError; on some event-loop/HTTP combinations a CancelledError-adjacent timeout during a long poll.
Common situations: Slow mobile/tethered connections where individual HTTP round-trips exceed httpx defaults; overloaded Replicate endpoints making even status GETs slow; event loop stalls from CPU-heavy work in the same process delaying async I/O.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Inference timed out
- Agent exceeded max tool turns
- Prediction ID not found in initial response.
- Invalid prediction status response.
- Inference errored out: {error_message}
AI-assisted analysis of abi/screenshot-to-code@d026163f58 (2026-08-14).
Data as JSON: /api/errors/c1b365a5b47d8e0b.
Report an issue: GitHub.