google-gemini/gemini-cli · error · FetchError
ETIMEDOUT
ETIMEDOUT
Error message
Request timed out after ${timeout}ms What it means
The HTTP request exceeded the per-call timeout and was aborted internally; the abort is converted into a FetchError with code ETIMEDOUT so the retry layer can treat it as retryable. It only fires when the caller's own signal was not already aborted (user cancellation is re-thrown as a plain AbortError instead).
Solutions
- Increase the timeout argument for slow endpoints
- Let the retry layer re-attempt the request
- Check network/proxy latency or server responsiveness
Defensive patterns
Strategy: retry
When it happens
Trigger: Thrown at packages/core/src/utils/fetch.ts:491 when the library encounters an invalid state.
Common situations: See trigger scenarios.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
AI-assisted analysis of google-gemini/gemini-cli@6a466a7e2f (2026-09-16).
Data as JSON: /api/errors/6d5f7e645de3a69d.
Report an issue: GitHub.
Appendix: source
Thrown at packages/core/src/utils/fetch.ts:491
if (!fetchOptions.dispatcher) {
fetchOptions.dispatcher = currentProxy
? createSafeProxyAgent(currentProxy)
: defaultSafeAgent;
}
const response = await fetch(url, fetchOptions);
return response;
} catch (error) {
if (isAbortError(error)) {
// If the caller's own signal was already aborted, this is a user-initiated
// cancellation (e.g. Ctrl+C), not an internal timeout. Re-throw as a plain
// AbortError so the retry layer does NOT treat it as a retryable ETIMEDOUT.
if (options?.signal?.aborted) {
// Rethrow the original abort reason or the caught error to preserve
// the stack trace and any custom abort reason (e.g. from Ctrl+C).
throw options.signal.reason ?? error;
}
throw new FetchError(`Request timed out after ${timeout}ms`, 'ETIMEDOUT');
}
if (error instanceof PrivateIpError) {
throw error;
}
if (error && typeof error === 'object' && 'cause' in error) {
if (error.cause instanceof PrivateIpError) {
throw error.cause;
}
}
throw new FetchError(getErrorMessage(error), undefined, { cause: error });
} finally {
clearTimeout(timeoutId);
}
}
export function setGlobalProxy(proxy: string) {
const trimmedProxy = proxy.trim();
currentProxy = trimmedProxy;View on GitHub (pinned to 6a466a7e2f)