Profiles·Public

@google/generative-ai

semver>=0.11.0 <1.0.0postconditions20functions13last verified2026-06-24coverage score93%

Postconditions: what we check

  • generateContent · network-error
    error
    Whenwhen the HTTP request fails (network error, timeout, 4xx/5xx response)
    ThrowsGoogleGenerativeAIFetchError with .status (HTTP status code) and .statusText. Common statuses: 400 (invalid request), 403 (API key invalid), 429 (quota exceeded), 500 (server error).
    Required handlingCaller MUST wrap generateContent() in try-catch. Check error.status to distinguish quota errors (429) from auth errors (403) from server errors (500). Quota errors should retry with backoff; auth errors should surface to the user.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • generateContent · safety-block
    warning
    Whenwhen the response resolves but response.text() is called on a safety-blocked response
    ThrowsGoogleGenerativeAIResponseError thrown synchronously from result.response.text() when the model blocked the request due to safety filters. The outer await generateContent() does NOT throw — the error is deferred to the response accessor. A try-catch around generateContent() + response.text() also catches this, so the network-error try-catch requirement covers it.
    Required handlingThe try-catch required for network-error also handles safety blocks. Callers may additionally check result.response.promptFeedback.blockReason to provide user-friendly messages when content is blocked.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[2]
  • generateContentStream · network-error
    error
    Whenwhen the HTTP request fails before the stream starts
    ThrowsGoogleGenerativeAIFetchError with .status and .statusText.
    Required handlingCaller MUST wrap generateContentStream() in try-catch. The await on the initial call can throw before any chunks are yielded.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • generateContentStream · stream-chunk-safety-block
    warning
    Whenwhen iterating the stream and chunk.text() is called on a safety-blocked chunk
    ThrowsGoogleGenerativeAIResponseError thrown synchronously from chunk.text() during stream iteration. The try-catch required for network-error covers this too.
    Required handlingThe try-catch required for network-error also handles stream chunk safety blocks.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[2]
  • sendMessage · network-error
    error
    Whenwhen the HTTP request fails
    ThrowsGoogleGenerativeAIFetchError with .status and .statusText.
    Required handlingCaller MUST wrap sendMessage() in try-catch. Same error handling as generateContent(): check .status for 429/403/500.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • sendMessage · safety-block
    warning
    Whenwhen the response resolves but result.response.text() is called on a safety-blocked response
    ThrowsGoogleGenerativeAIResponseError thrown synchronously from result.response.text(). The try-catch required for network-error covers this too.
    Required handlingThe try-catch required for network-error also handles safety blocks.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[2]
  • sendMessageStream · network-error
    error
    Whenwhen the HTTP request fails before the stream starts
    ThrowsGoogleGenerativeAIFetchError with .status and .statusText.
    Required handlingCaller MUST wrap sendMessageStream() in try-catch.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • sendMessageStream · stream-chunk-safety-block
    warning
    Whenwhen iterating the stream and chunk.text() is called on a blocked chunk
    ThrowsGoogleGenerativeAIResponseError thrown synchronously from chunk.text(). The try-catch required for network-error covers this too.
    Required handlingThe try-catch required for network-error also handles stream chunk safety blocks.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[2]
  • embedContent · network-error
    error
    Whenwhen the HTTP request fails
    ThrowsGoogleGenerativeAIFetchError with .status and .statusText.
    Required handlingCaller MUST wrap embedContent() in try-catch.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • countTokens · network-error
    error
    Whenwhen the HTTP request fails
    ThrowsGoogleGenerativeAIFetchError with .status and .statusText.
    Required handlingCaller MUST wrap countTokens() in try-catch.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • batchEmbedContents · batch-network-error
    error
    WhenAny HTTP error during the batch embedding request: invalid API key (403), rate limit exceeded (429), server error (500/503), network timeout, or invalid request parameters (400).
    ThrowsGoogleGenerativeAIFetchError with .status (HTTP code) and .statusText. Key statuses: 400 (INVALID_ARGUMENT — malformed request or input exceeds token limit; 2048 tokens for text-embedding-001, 8192 for embedding-001), 403 (PERMISSION_DENIED — invalid API key), 429 (RESOURCE_EXHAUSTED — rate limit or tokens-per-minute quota exceeded), 500 (INTERNAL — unexpected server error), 503 (UNAVAILABLE — service overloaded).
    Required handlingCaller MUST wrap batchEmbedContents() in try-catch. Batch embedding pipelines commonly run without try-catch because individual embedContent() calls are wrapped but the batch variant is not. A 429 on a large batch means ALL embeddings failed — retry with exponential backoff or reduce batch size. try { const result = await model.batchEmbedContents({ requests: chunks }); return result.embeddings; } catch (err) { if (err instanceof GoogleGenerativeAIFetchError) { if (err.status === 429) { // Rate limit — retry with backoff or split batch } throw new Error(`Embedding batch failed: ${err.status} ${err.statusText}`); } throw err; }
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilitysilent
    Sources[3][4]
  • batchEmbedContents · batch-input-validation
    warning
    WhenAny individual request in the batch has invalid content: text exceeds model token limit, unsupported content type, or both ttlSeconds and expireTime specified (GoogleGenerativeAIRequestInputError from input validation).
    ThrowsGoogleGenerativeAIRequestInputError (subclass of GoogleGenerativeAIError) thrown synchronously before any network call when input validation fails. GoogleGenerativeAIFetchError with status 400 (INVALID_ARGUMENT) when validation fails on the server side.
    Required handlingThe try-catch required for batch-network-error also handles input errors. In RAG pipelines, catch and log which chunk failed, skip it, and continue with the rest of the batch rather than halting the entire ingestion run.
    costmediumin prodimmediate exceptionusers seelost datavisibilitysilent
    Sources[4]
  • GoogleAIFileManager.uploadFile · upload-network-error
    error
    WhenHTTP error during the multipart upload: invalid API key (403), file too large (400 when exceeding 2 GB limit or 50 MB PDF limit), storage quota exceeded (403 or 429 when the 20 GB project quota is full), server error (500/503), unsupported MIME type (400), or network failure.
    ThrowsGoogleGenerativeAIFetchError with .status and .statusText. Key statuses: 400 (file too large, invalid MIME type, malformed request), 403 (invalid API key OR quota exceeded — check statusText to distinguish), 429 (RESOURCE_EXHAUSTED — rate limit), 500/503 (server error).
    Required handlingCaller MUST wrap uploadFile() in try-catch. File upload errors are silent in systems that fire-and-forget the upload before a generation call. Also: uploadFile() returning does NOT mean the file is ready — poll fileManager.getFile(file.name) until file.state === FileState.ACTIVE before using the file URI in a generateContent() call. try { const uploadResult = await fileManager.uploadFile(buffer, { mimeType: 'image/jpeg' }); // Wait for processing let file = uploadResult.file; while (file.state === FileState.PROCESSING) { await new Promise(r => setTimeout(r, 5000)); file = await fileManager.getFile(file.name); } if (file.state === FileState.FAILED) { throw new Error('File processing failed'); } } catch (err) { if (err instanceof GoogleGenerativeAIFetchError) { console.error('Upload failed:', err.status, err.statusText); } throw err; }
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[5][3]
  • GoogleAIFileManager.uploadFile · upload-file-processing-failed
    error
    WhenuploadFile() succeeds (returns without throwing) but the returned FileMetadataResponse.state is PROCESSING — callers who immediately use the file URI without polling for ACTIVE state will get an error from generateContent(). If the file transitions to state === FAILED, the file is unusable.
    ThrowsGoogleGenerativeAIFetchError (from generateContent()) when a PROCESSING or FAILED file URI is referenced in a multimodal generation request. The file upload itself does NOT throw in this case.
    Required handlingCaller MUST poll getFile(file.name) after upload until file.state === FileState.ACTIVE. Check file.state === FileState.FAILED and throw a meaningful error if processing failed (e.g., corrupted video, unsupported codec).
    costmediumin prodsilent failureusers seeservice unavailablevisibilitysilent
    Sources[5]
  • GoogleAICacheManager.create · cache-create-validation-error
    error
    WhencreateOptions.model is not provided, OR both ttlSeconds and expireTime are specified simultaneously (must choose one or neither).
    ThrowsGoogleGenerativeAIRequestInputError thrown synchronously before any network call. Messages: - "Cached content must contain a `model` field." - "You cannot specify both `ttlSeconds` and `expireTime` when creating a content cache. You must choose one."
    Required handlingCaller MUST wrap create() in try-catch. Input validation errors are thrown synchronously — they indicate a programming error in how the cache is configured. Ensure model is always specified and only one TTL format is used. try { const cache = await cacheManager.create({ model: 'models/gemini-1.5-flash', contents: systemContents, ttlSeconds: 3600, }); } catch (err) { if (err instanceof GoogleGenerativeAIRequestInputError) { console.error('Cache config error:', err.message); } else if (err instanceof GoogleGenerativeAIFetchError) { console.error('Cache API error:', err.status, err.statusText); } throw err; }
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[6]
  • GoogleAICacheManager.create · cache-create-api-error
    error
    WhenHTTP error during cache creation: model not found (404), insufficient tokens to meet minimum caching threshold (400), rate limit (429), auth error (403), or server error (500/503).
    ThrowsGoogleGenerativeAIFetchError with .status and .statusText. Key status 400 (FAILED_PRECONDITION) when the cached content doesn't meet the minimum token count for the model (Gemini 1.5 Flash: 1024 tokens, Gemini 1.5 Pro: 4096 tokens). Creating a cache with too few tokens results in a confusing 400 error that callers often miss.
    Required handlingThe try-catch required for cache-create-validation-error also handles API errors. For status 400 with FAILED_PRECONDITION: increase the amount of content being cached or switch to a non-caching approach for small prompts.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[6][3]
  • GoogleAICacheManager.update · cache-update-not-found
    error
    WhenThe cache name is not found (deleted, expired, or never existed), or the name format is invalid (must contain a "/" separator per source validation at dist/server/index.js:587).
    ThrowsGoogleGenerativeAIFetchError with status 404 (NOT_FOUND) when the cache no longer exists — common when a cache expires between the time it was created and when update() is called to extend its TTL. GoogleGenerativeAIError thrown synchronously for invalid name format.
    Required handlingCaller MUST wrap update() in try-catch. Cache expiration is a normal lifecycle event — a 404 from update() means the window to extend the cache has passed and a new cache must be created. try { await cacheManager.update(cache.name, { cachedContent: { ttlSeconds: 7200 } }); } catch (err) { if (err instanceof GoogleGenerativeAIFetchError && err.status === 404) { // Cache expired — recreate it cache = await cacheManager.create({ ... }); } else { throw err; } }
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[6][3]
  • GoogleAIFileManager.getFile · getfile-network-error
    error
    WhenHTTP error during the file metadata request: file expired or never existed (404 NOT_FOUND — files auto-expire after 48 hours), invalid API key (403), rate limit (429), server error (500/503), or network failure during a polling loop.
    ThrowsGoogleGenerativeAIFetchError with .status (HTTP code) and .statusText. Key status 404 (NOT_FOUND) when the file has expired past its 48-hour TTL or was deleted by a concurrent deleteFile() call — common in long-running polling loops that started before the file was uploaded.
    Required handlingCaller MUST wrap getFile() in try-catch, especially when used inside the recommended polling loop after uploadFile(). A network blip mid-poll currently crashes the whole upload flow. A 404 mid-poll means the file was either deleted out-of-band or the file ID is wrong — distinct from PROCESSING/FAILED state which is signalled by the returned metadata, not by an exception. try { let file = uploadResult.file; while (file.state === FileState.PROCESSING) { await new Promise(r => setTimeout(r, 5000)); file = await fileManager.getFile(file.name); } } catch (err) { if (err instanceof GoogleGenerativeAIFetchError && err.status === 404) { throw new Error(`File ${fileName} no longer exists (expired or deleted)`); } throw err; }
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitysilent
    Sources[5][3]
  • GoogleAIFileManager.deleteFile · deletefile-network-error
    error
    WhenHTTP error during the file deletion request: file not found (404 — already deleted, expired past 48-hour TTL, or wrong ID), invalid API key (403), rate limit (429), or server error (500/503).
    ThrowsGoogleGenerativeAIFetchError with .status and .statusText. Key status 404 when the file is already gone — common in cleanup paths that run after the 48-hour TTL has expired, or when retry logic accidentally calls deleteFile() twice on the same ID. GoogleGenerativeAIError thrown synchronously when fileId is empty or undefined.
    Required handlingCaller MUST wrap deleteFile() in try-catch. Cleanup paths in finally blocks that don't catch this turn a successful generation flow into a runtime crash on completion. A 404 from deleteFile() during cleanup is usually safe to ignore (the file is already gone — the goal was achieved). Other status codes should be logged but rarely surfaced to the user. try { await fileManager.deleteFile(file.name); } catch (err) { if (err instanceof GoogleGenerativeAIFetchError && err.status === 404) { // File already gone — cleanup goal achieved, swallow } else { console.error('File cleanup failed:', err); } }
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[5][3]
  • GoogleAICacheManager.delete · cache-delete-network-error
    error
    WhenHTTP error during the cache deletion request: cache name not found (404 — already deleted, TTL expired, or wrong name), invalid API key (403), rate limit (429), or server error (500/503). Also: invalid name format (missing "/" separator) throws synchronously before the network call.
    ThrowsGoogleGenerativeAIFetchError with .status and .statusText. Key status 404 when the cache has expired between create() and delete() — cache TTLs are short by default (5 minutes minimum), so a 404 on delete is a normal lifecycle event in any cache-cleanup path. GoogleGenerativeAIError thrown synchronously for invalid name format.
    Required handlingCaller MUST wrap delete() in try-catch. Cache-cleanup logic that runs after a generation request may find the cache has already expired — 404 in this case is the desired terminal state (cache is gone) and should be swallowed. Non-404 errors should be logged so storage quota leaks are visible. try { await cacheManager.delete(cache.name); } catch (err) { if (err instanceof GoogleGenerativeAIFetchError && err.status === 404) { // Cache already expired — fine, that was the goal } else { console.error('Cache delete failed:', err); } }
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[6][3]

Sources

Every postcondition cites at least one of these. Grouped by source type; numbered to match the footnotes above.

Official documentation
Source code

Research notes

Curator notes from SOURCES.md captured when the profile was written so you can verify the reasoning, not just the rules.

Sources: @google/generative-ai

All behavioral claims in contract.yaml are documented here with primary sources.

Official Documentation

Package Source (Error Types)

  • Error class definitions https://github.com/google-gemini/generative-ai-js/blob/main/src/errors.ts Source of truth for exported error classes:

    • GoogleGenerativeAIError — base class
    • GoogleGenerativeAIFetchError — network/HTTP errors (.status, .statusText, .errorDetails)
    • GoogleGenerativeAIResponseError<T> — deferred error from response.text() on blocked content
    • GoogleGenerativeAIRequestInputError — malformed input
    • GoogleGenerativeAIAbortError — timeout / AbortSignal cancellation (added 0.23.0)
  • npm package registry https://www.npmjs.com/package/@google/generative-ai Version history and deprecation notice (EOL: November 30, 2025; replaced by @google/genai).

Key Behavioral Claims

generateContent / sendMessage throw at the network layer

GoogleGenerativeAIFetchError is thrown when the HTTP request fails. Confirmed in src/fetch.ts in the package source — the makeRequest() function wraps fetch() and converts HTTP error responses into GoogleGenerativeAIFetchError.

Source: https://github.com/google-gemini/generative-ai-js/blob/main/src/requests/request.ts

Safety blocks are deferred errors from response accessors

When the Gemini API returns a response with finishReason: "SAFETY" or promptFeedback.blockReason set, calling response.text() throws GoogleGenerativeAIResponseError synchronously. The await generateContent() call itself does not throw. This is the most common source of unexpected production crashes.

Source: https://github.com/google-gemini/generative-ai-js/blob/main/src/types/response-helpers.ts Source: https://ai.google.dev/gemini-api/docs/safety-settings

Streaming errors

For generateContentStream / sendMessageStream, the same patterns apply:

  • The initial await can throw GoogleGenerativeAIFetchError
  • chunk.text() during iteration can throw GoogleGenerativeAIResponseError on blocked chunks

Source: https://github.com/google-gemini/generative-ai-js/blob/main/src/methods/generate-content.ts

Security Notes

No CVEs have been published for this package. The main security risk is API key exposure — keys of the form AIzaSy* in public repositories can be used to make unauthorized Gemini API calls at the account owner's expense (up to thousands of dollars/day).

The package reached EOL November 30, 2025. No future security patches will be issued. Migration path: @google/genai (the unified Google AI SDK).

Version Range

Semver: >=0.11.0 <1.0.0

Confirmed in production (found in test-repos/):

  • chatbot-ui: ^0.11.4
  • n8n: 0.24.0

The error API (GoogleGenerativeAIFetchError, GoogleGenerativeAIResponseError) has been stable across this range. The GoogleGenerativeAIAbortError was added in 0.23.0 but is not covered by this contract.

Need a different package?
Request a profile