thedotmack/claude-mem · error · ServerClassifiedProviderError
Gemini HTTP error (status )
Error message
Gemini HTTP error (status ${response.status}) What it means
The Gemini generateContent endpoint returned a non-2xx status. GeminiObservationProvider reads the body and calls classifyGeminiServerError with status/bodyText/headers and cause `Gemini HTTP error (status <status>)`. The Gemini classifier adds special handling: 400 without quota markers becomes 'unrecoverable' with a categorized bad-request message, and quota bodies map to rate-limit handling.
Solutions
- Check status: 429/quota → honor Retry-After and back off; 400 → fix model name and request payload (must use v1beta for Gemini 3.x models).
- Verify the GEMINI/GOOGLE API key and its region/permission settings.
- Reduce request rate or request a quota increase for the project.
- Inspect the bodyText in the cause for Google's exact error message.
Example fix
// before url = 'https://generativelanguage.googleapis.com/v1/models/...'; // after url = 'https://generativelanguage.googleapis.com/v1beta/models/...';
Defensive patterns
Strategy: retry
Validate before calling
if (!process.env.GEMINI_API_KEY) throw new Error('GEMINI_API_KEY not set');
if (!/v1beta/.test(baseUrl)) throw new Error('Gemini requires v1beta API version'); Type guard
function isRetryableProviderError(e: unknown): boolean {
return typeof e === 'object' && e !== null && 'kind' in e && (e as {kind: string}).kind === 'retryable';
} Try / catch
try {
result = await geminiProvider.generate(prompt, signal);
} catch (e) {
if (e.kind === 'retryable' && e.retryAfterMs) return sleep(e.retryAfterMs).then(call);
throw e;
} Prevention
- Always use the v1beta endpoint for current Gemini models.
- Track quota usage; back off on 429 and respect Retry-After.
- Verify API key region eligibility and billing enabled on the project.
- Read bodyText in the cause for Google's specific error message.
When it happens
Trigger: `response.ok` is false after postGenerateContent: 400 invalid API version/model/payload, 403 key restricted, 429 quota exceeded, 5xx Google-side errors — thrown at GeminiObservationProvider.ts:172-179.
Common situations: Calling v1 instead of required v1beta API version, invalid or region-locked API key, exhausting free-tier requests-per-minute or per-day quota, sending unsupported payload fields.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- Anthropic API error
- classifyGeminiServerError
- Gemini API error (status )
- OpenRouter API error
- Aborting session for quota guard
AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17).
Data as JSON: /api/errors/2ac67e7e5970ff87.
Report an issue: GitHub.
Appendix: source
Thrown at src/server/generation/providers/GeminiObservationProvider.ts:175
modelId: this.model,
};
}
const url = `${GEMINI_API_URL}/${encodeURIComponent(this.model)}:generateContent?key=${encodeURIComponent(this.apiKey)}`;
let response: Response;
try {
response = await this.postGenerateContent(url, prompt, signal);
} catch (networkError) {
const err = networkError instanceof Error ? networkError : new Error(String(networkError));
throw classifyGeminiServerError({
cause: err,
});
}
if (!response.ok) {
const bodyText = await safeReadBody(response);
throw classifyGeminiServerError({
status: response.status,
bodyText,
headers: response.headers,
cause: new Error(`Gemini HTTP error (status ${response.status})`),
});
}
let data: GeminiResponse;
try {
data = (await response.json()) as GeminiResponse;
} catch (parseError) {
const err = parseError instanceof Error ? parseError : new Error(String(parseError));
throw new ServerClassifiedProviderError('Gemini returned invalid JSON', {
kind: 'parse_error',
cause: err,
});
}
View on GitHub (pinned to d8bc9755e7)