{"record":{"id":"7266bedaa3052933","repo":"thedotmack/claude-mem","slug":"classifygeminiservererror-cause-err","errorCode":null,"errorMessage":"classifyGeminiServerError({ cause: err })","messagePattern":"classifyGeminiServerError\\((.+?)\\)","errorType":"exception","errorClass":"ServerClassifiedProviderError","httpStatus":null,"severity":"error","filePath":"src/server/generation/providers/GeminiObservationProvider.ts","lineNumber":168,"sourceCode":"    signal?: AbortSignal,\n  ): Promise<ServerGenerationResult> {\n    const { prompt, skippedAll } = buildServerGenerationPrompt(context);\n    if (skippedAll) {\n      return {\n        rawText: '<skip_summary reason=\"all_events_private\" />',\n        providerLabel: this.providerLabel,\n        modelId: this.model,\n      };\n    }\n\n    const url = `${GEMINI_API_URL}/${encodeURIComponent(this.model)}:generateContent?key=${encodeURIComponent(this.apiKey)}`;\n\n    let response: Response;\n    try {\n      response = await this.postGenerateContent(url, prompt, signal);\n    } catch (networkError) {\n      const err = networkError instanceof Error ? networkError : new Error(String(networkError));\n      throw classifyGeminiServerError({\n        cause: err,\n      });\n    }\n\n    if (!response.ok) {\n      const bodyText = await safeReadBody(response);\n      throw classifyGeminiServerError({\n        status: response.status,\n        bodyText,\n        headers: response.headers,\n        cause: new Error(`Gemini HTTP error (status ${response.status})`),\n      });\n    }\n\n    let data: GeminiResponse;\n    try {\n      data = (await response.json()) as GeminiResponse;\n    } catch (parseError) {","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/server/generation/providers/GeminiObservationProvider.ts#L150-L186","documentation":"GeminiObservationProvider.generate wraps its call to the Gemini generateContent endpoint; a rejected postGenerateContent (no HTTP response at all) is rethrown via classifyGeminiServerError with only a cause. It indicates a transport-level failure — DNS, connection, TLS, timeout, or abort — before Google's API could answer.","triggerScenarios":"`postGenerateContent()` rejects: network unreachable, DNS failure, connection reset, timeout, or AbortSignal fired — caught at GeminiObservationProvider.ts:164-171 and wrapped as classifyGeminiServerError({ cause: err }).","commonSituations":"Corporate firewall blocking generativelanguage.googleapis.com, no internet in the container, GEMINI base URL/proxy misconfiguration, request timeout for very long prompts.","solutions":["Verify connectivity to generativelanguage.googleapis.com (curl/ping).","Check proxy/firewall/egress rules in the runtime environment.","Increase client timeout if long prompts cause timeouts; pass a longer AbortSignal.","Retry with backoff for transient causes (reset, timeout)."],"exampleFix":"// before\nconst r = await geminiProvider.generate(prompt, signal);\n// after\ntry { const r = await geminiProvider.generate(prompt, signal); }\ncatch (e) { if (isTransientNetwork(e)) return retryWithBackoff(); throw e; }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isNetworkError(e: unknown): e is TypeError {\n  return e instanceof TypeError && /fetch|network/i.test(e.message);\n}","tryCatchPattern":"try {\n  result = await geminiProvider.generate(prompt, signal);\n} catch (e) {\n  if (e.kind === 'retryable') return retryWithBackoff(() => geminiProvider.generate(prompt, signal));\n  throw e;\n}","preventionTips":["Verify egress to generativelanguage.googleapis.com in all environments.","Configure proxy env vars if traffic must traverse a corporate proxy.","Set generous but bounded timeouts via AbortSignal.","Inspect the wrapped cause for the true network failure."],"tags":["network","gemini","google","transport-error"],"backgroundTag":"network-request-failed","analyzedSha":"d8bc9755e74915e5c3b999181e10a67c889bce2a","analyzedAt":"2026-09-17T16:40:26.182Z","contentChangedAt":"2026-09-17T16:40:26.182Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}