Significant-Gravitas/AutoGPT · error · HTTPException
Request to Otto service timed out
Error message
Request to Otto service timed out
What it means
Raised by OttoService.ask when the upstream Otto API does not respond within the 60-second total aiohttp timeout (asyncio.TimeoutError is caught and mapped to a 504). It means the upstream accepted the connection but was too slow to complete the response.
Source
Thrown at autogpt_platform/backend/backend/api/features/otto/service.py:133
raise HTTPException(
status_code=response.status,
detail=f"Otto API request failed: {error_text}",
)
data = await response.json()
logger.info(
f"Successfully received response from Otto API for user {user_id}"
)
return ApiResponse(**data)
except aiohttp.ClientError as e:
logger.error(f"Connection error to Otto API: {str(e)}")
raise HTTPException(
status_code=503, detail="Failed to connect to Otto service"
)
except asyncio.TimeoutError:
logger.error("Timeout error connecting to Otto API after 60 seconds")
raise HTTPException(
status_code=504, detail="Request to Otto service timed out"
)
except Exception as e:
logger.error(f"Unexpected error in Otto API proxy: {str(e)}")
raise HTTPException(
status_code=500, detail="Internal server error in Otto proxy"
)
View on GitHub (pinned to 9c8bb5550f)
Solutions
- Check Otto service latency/health — a 60s+ response usually means the upstream is degraded or the request is too heavy.
- Reduce payload size (e.g. trim graph data) or split the request if Otto processes large contexts slowly.
- If long responses are expected, raise the aiohttp ClientTimeout and any intermediate proxy timeouts to match.
- Add client-side timeout handling and avoid immediate tight retries that amplify upstream load.
Example fix
# before timeout=aiohttp.ClientTimeout(total=60) # after — budget aligned with expected Otto latency timeout=aiohttp.ClientTimeout(total=120, connect=5)
Defensive patterns
Strategy: retry
Validate before calling
// Client-side: cap own timeout under the server's 60s so users get feedback first const ctrl = new AbortController(); setTimeout(() => ctrl.abort(), 50_000);
Try / catch
try { return await otto.ask(req); }
catch (e) {
if (e.status === 504) { // only retry once; timeouts often mean upstream overload
return await otto.ask(req);
}
throw e;
} Prevention
- Show streaming/progress UI so users don't abandon and re-fire long requests.
- Trim large graph payloads before proxying.
- Set gateway/LB timeouts >= the backend's 60s budget to avoid double timeouts.
When it happens
Trigger: Chat requests where Otto takes longer than the 60s ClientTimeout(total=60) — long-running LLM generation, Otto stuck waiting on its own dependencies, or degraded upstream performance under load.
Common situations: Large graph payloads making Otto slow; Otto's own model/DB bottleneck; occasional tail-latency spikes that exceed the fixed budget; clients without their own timeout retrying and stacking load.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Webhook ping timed out
- Failed to connect to Otto service
- str(e)
- Otto service is not configured
- Otto API request failed: {error_text}
AI-assisted analysis of Significant-Gravitas/AutoGPT@9c8bb5550f (2026-08-14).
Data as JSON: /api/errors/5f358dabedb117ad.
Report an issue: GitHub.