Errors
Understand SDK errors, error codes, retry behavior, and how to handle failures safely.
The SDK provides typed errors for configuration, authentication, upstream requests, timeouts, cancellation, protocol failures, and structured output. These errors extend GeminiError and expose a code and retryable property. Some failures, such as an unavailable fetch implementation, can still produce native JavaScript errors.
Initialize the client
Configure the session cookies and XSRF token from the same signed-in Gemini Web session before making requests. The SDK does not load environment variables automatically.
import 'dotenv/config'import { GeminiWeb, GeminiAuthenticationError, GeminiRateLimitError, GeminiAbortError, isGeminiError,} from '@orcushq/gemini' const cookies = process.env.GEMINI_COOKIESconst xsrfToken = process.env.GEMINI_XSRF_TOKEN if (!cookies?.trim() || !xsrfToken?.trim()) { throw new Error( 'GEMINI_COOKIES and GEMINI_XSRF_TOKEN are required', )} const clientConfig = { model: 'gemini-3.6-flash', cookies, xsrfToken,} const model = new GeminiWeb(clientConfig)GEMINI_COOKIES="your_complete_cookie_header"GEMINI_XSRF_TOKEN="your_at_value"Error Types
- `GeminiConfigurationError` — Invalid configuration, unsupported input, an empty prompt, or an unknown model when
unknownModel: "throw"is configured. Not retryable by default. - `GeminiAuthenticationError` — Authentication failures such as HTTP 401 or 403. Check your session cookies and authentication settings.
- `GeminiUpstreamError` — Upstream HTTP failures, network errors, and other request failures. Retryability depends on the failure and its status.
- `GeminiBardError` — A specific upstream error identified by a
BardErrorInfomarker. ExtendsGeminiUpstreamError, uses codeupstream, and includesbardErrorCodein its details. - `GeminiRateLimitError` — HTTP 429 responses. May include
retryAfterMswhen a retry delay is provided by the server. The supplied implementation marks this error non-retryable. - `GeminiTimeoutError` — A request exceeds its configured timeout. Includes timeout details and is marked non-retryable by the supplied implementation.
- `GeminiAbortError` — A request is cancelled through an abort signal. Not retryable.
- `GeminiProtocolError` — The response cannot be processed as expected, such as when a streaming response has no readable body or violates the expected protocol.
- `GeminiStructuredOutputError` — Structured-output schema conversion, JSON extraction, parsing, or validation fails.
Error Properties
codeidentifies the error category using theGeminiErrorCodetype.retryableindicates whether the SDK retry mechanism may retry the failure. It does not guarantee that a retry will occur.statuscontains the HTTP status when available.detailscontains additional structured information, depending on the error.causepreserves the underlying error when provided.
Retryability depends on the error constructor and the failure being mapped. Upstream HTTP 5xx responses are retryable by default, while certain statuses such as 400 and 405 are explicitly non-retryable. Authentication, rate-limit, timeout, abort, and configuration errors should not be assumed to retry automatically.
Retry Behavior
The SDK retries eligible request failures according to its retry policy. The default policy allows 3 total attempts, including the initial request, with a 2,000 ms base delay, a backoff factor of 2, and a maximum delay of 30,000 ms.
const retryingModel = new GeminiWeb({ ...clientConfig, retry: { attempts: 3, delayMs: 2_000, backoffFactor: 2, maxDelayMs: 30_000, },}) // Disable retries for one invocation.const response = await model.invoke('Hello', { retry: false,}) console.log(response.content)Retries occur only when enabled, attempts remain, and the failure is considered retryable. When a Retry-After value is available, the SDK may use it as a delay hint and clamp the delay to maxDelayMs. See Reliability.
import { DEFAULT_RETRY_POLICY } from '@orcushq/gemini' console.log(DEFAULT_RETRY_POLICY)// {// attempts: 3,// delayMs: 2000,// backoffFactor: 2,// maxDelayMs: 30000// }Rate limits
HTTP 429 raises GeminiRateLimitError. When the upstream response provides a retry hint, retryAfterMs contains the suggested delay. Use the provided value rather than guessing a delay.
const sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms)) try { await model.invoke('Explain rate limiting.')} catch (error) { if (error instanceof GeminiRateLimitError) { const delayMs = error.retryAfterMs ?? 1_000 console.warn('Rate limit reached. Retry delay:', delayMs) await sleep(delayMs) } else { throw error }}Provider-managed limits
Requests go directly to Gemini Web. Applicable quotas and rate limits depend on the provider and the authenticated session. Retries do not increase provider limits or resolve sustained overuse.
Cancellation
Pass an AbortSignal to request cancellation. You can configure a signal on the client or provide one for an individual invocation.
const controller = new AbortController() const cancellableModel = new GeminiWeb({ ...clientConfig, signal: controller.signal,}) const timer = setTimeout( () => controller.abort(), 5_000,) try { await cancellableModel.invoke( 'Explain how distributed systems work.', )} catch (error) { if (error instanceof GeminiAbortError) { console.log('Request cancelled.') } else { throw error }} finally { clearTimeout(timer)} // Use a separate signal for one invocation.const callController = new AbortController() await model.invoke( 'Explain request cancellation.', { signal: callController.signal },)A client-level signal and a per-call signal can both be configured. Handle cancellation errors in your application and verify the specific error type for the operation being cancelled.
Non-Throwing Fallbacks
Not every internal failure is propagated as an exception. For example, image-upload page-token retrieval can fall back to built-in tokens when retrieval fails. Abort-related failures are handled separately. This fallback behavior does not mean every image upload will succeed.
Model Fallback Is Not Necessarily an Error
A request can succeed even when Gemini serves a different model than requested. When the response provides sufficient evidence, the SDK reports fallback information in response metadata instead of necessarily throwing an error.
Verify the served model
If model identity matters, inspect `metadata.modelFellBack`, `metadata.fallbackReason`, `metadata.fallbackNotice`, and the requested and served model identifiers available in the response metadata.
See Served Model Evidence for details.
Error Codes
The GeminiErrorCode type defines the supported SDK error categories. Use the error class and code together when implementing application-level error handling. See the Error Codes Reference for the complete list.
Handling Errors
try { const response = await model.invoke('Hello') console.log(response.content)} catch (error) { if (error instanceof GeminiAbortError) { console.log('Request cancelled.') } else if (error instanceof GeminiRateLimitError) { console.warn('Rate limit reached:', error.retryAfterMs) } else if (error instanceof GeminiAuthenticationError) { console.error('Check Gemini session credentials.') } else if (isGeminiError(error)) { console.error(error.code, error.message, error.details) } else { // Preserve unexpected native or application errors. throw error }}Use error classes or isGeminiError() to identify SDK errors. Keep a final fallback for unexpected errors, because not every failure is guaranteed to be a GeminiError.
Error Details and Security
includeErrorBody is disabled by default. Enabling it can include a truncated snippet of the upstream response body in HTTP error messages. Enable it only when needed, and avoid exposing error details or credentials in production logs.