different-ai/openwork · error
Request timed out.
Error message
Request timed out.
What it means
fetchWithTimeout races the fetch against a timeout promise; if the loser is an AbortError (raised by the abort controller when the deadline elapses), it is rethrown as "Request timed out." This distinguishes deadline aborts from other failures. Used by createDesktopFetch and fetchImpl.
Source
Thrown at apps/app/src/app/lib/opencode.ts:169
let timeoutId: ReturnType<typeof setTimeout> | null = null;
const timeoutPromise = new Promise<never>((_, reject) => {
timeoutId = setTimeout(() => {
try {
controller?.abort();
} catch {
// ignore
}
reject(new Error("Request timed out."));
}, effectiveTimeoutMs);
});
try {
return await Promise.race([fetchImpl(input, initWithSignal), timeoutPromise]);
} catch (error) {
const name = (error && typeof error === "object" && "name" in error ? (error as any).name : "") as string;
if (name === "AbortError") {
throw new Error("Request timed out.");
}
throw error;
} finally {
if (timeoutId) clearTimeout(timeoutId);
}
}
const encodeBasicAuth = (auth?: OpencodeAuth) => {
if (!auth?.username || !auth?.password) return null;
const token = `${auth.username}:${auth.password}`;
if (typeof btoa === "function") return btoa(token);
const buffer = (globalThis as { Buffer?: { from: (input: string, encoding: string) => { toString: (encoding: string) => string } } })
.Buffer;
return buffer ? buffer.from(token, "utf8").toString("base64") : null;
};
const resolveAuthHeader = (auth?: OpencodeAuth) => {
if (auth?.mode === "openwork" && auth.token) {View on GitHub (pinned to 2b7df46e8a)
Solutions
- Retry the request; transient timeouts often succeed on a second attempt.
- Increase the timeout passed to fetchWithTimeout for slow endpoints (e.g. server startup polling).
- Verify the target host is reachable (curl) to rule out network/proxy issues.
- Check whether the server is hung and needs restart rather than the client needing more time.
Example fix
// before: single attempt
const res = await fetchWithTimeout(url, { timeoutMs: 5000 });
// after: bounded retry for timeout
let res;
for (let i = 0; i < 3; i++) {
try { res = await fetchWithTimeout(url, { timeoutMs: 5000 }); break; }
catch (e) { if (i === 2 || String(e.message).includes("timed out") === false) throw e; }
} Defensive patterns
Strategy: retry
Validate before calling
// can only be detected at runtime; ensure timeout exceeds worst-case latency
const timeoutMs = endpoint.slow ? 30000 : 5000;
await fetchWithTimeout(url, { timeoutMs }); Try / catch
try {
const res = await fetchWithTimeout(url, init);
} catch (err) {
if (err instanceof Error && err.message === "Request timed out.") {
// deadline hit: retry with backoff or enlarge timeout
return retryWithBackoff(() => fetchWithTimeout(url, { ...init, timeoutMs: init.timeoutMs * 2 }), 2);
}
throw err;
} Prevention
- Set per-endpoint timeouts sized to realistic worst-case latency.
- Retry idempotent GETs automatically on timeout.
- Use health polling with generous budgets during server cold starts.
- Monitor network paths (VPN/proxy) known to add latency.
When it happens
Trigger: Any fetch routed through fetchWithTimeout that exceeds its configured timeout: slow network, hung server, large body with no streaming, DNS stall. The abort signal fires and the race rejects with AbortError.
Common situations: First-run server health checks against a slow-to-boot local server, remote API latency spikes, VPN/proxy slowness, or a timeout value set too aggressively for the endpoint.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- source_fetch_failed
- Failed to fetch latest-mac.yml (${response.status} ${respons
- Timed out waiting for server health
- Connection lost
- MCP_SHUTDOWN_FAILED
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/99d3fbcc831416c3.
Report an issue: GitHub.