nexu-io/open-design · error · Error

google ${resp.status}: ${await resp.text().catch(() => '')}

Error message

google ${resp.status}: ${await resp.text().catch(() => '')}

What it means

The Google Gemini REST API returned a non-2xx HTTP status during the memory-LLM extraction call. Gemini uses a different request shape (systemInstruction, contents[], query-param API key) and response_format: application/json for strict JSON output. The error includes status code and raw body.

Source

Thrown at apps/daemon/src/memory-llm.ts:917

  const model = encodeURIComponent(provider.model);
  const url = `${base}/v1beta/models/${model}:generateContent?key=${encodeURIComponent(provider.apiKey)}`;
  let resp;
  try {
    resp = await fetch(url, {
      method: 'POST',
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify({
        systemInstruction: { role: 'system', parts: [{ text: system }] },
        contents: [{ role: 'user', parts: [{ text: user }] }],
        generationConfig: { responseMimeType: 'application/json' },
      }),
      signal: withTimeout(FETCH_TIMEOUT_MS),
    });
  } catch (err) {
    throw new Error(describeFetchError(err));
  }
  if (!resp.ok) {
    throw new Error(`google ${resp.status}: ${await resp.text().catch(() => '')}`);
  }
  const json = await resp.json();
  const parts = json?.candidates?.[0]?.content?.parts;
  if (Array.isArray(parts)) {
    return parts.map((p) => (p && typeof p.text === 'string' ? p.text : '')).join('');
  }
  return '';
}

const LOCAL_CLI_TIMEOUT_MS = 60_000;

function extractJsonEventText(kind, raw, agentName) {
  const events = [];
  const handler = createJsonEventStreamHandler(kind, (event) => events.push(event));
  handler.feed(raw);
  handler.flush();

  const errorEvent = events.find((event) => event?.type === 'error');

View on GitHub (pinned to 5be4028344)

Solutions

  1. Verify the Google API key is valid and has Gemini API access enabled
  2. Confirm provider.model is a current Gemini model identifier
  3. Check provider.baseUrl points to the correct Google Generative AI endpoint
  4. Inspect the response body for the specific error (safety blocks return 400 with finishReason)
  5. Retry after a delay if quota-limited
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const text = await callGoogle(provider, system, user);
} catch (err) {
  if (err.message.startsWith('google ')) {
    const status = parseInt(err.message.split(' ')[1], 10);
    if (status === 429) {
      await sleep(backoffMs);
      return callGoogle(provider, system, user);
    }
    if (status === 400) {
      // Could be a safety filter block — inspect the body
      throw new Error('Google Gemini rejected the request (possibly safety filter): ' + err.message);
    }
  }
  throw err;
}

Prevention

When it happens

Trigger: Invalid or expired API key (passed as query parameter); model name not available; quota exceeded; safety filters triggered; malformed request; wrong baseUrl.

Common situations: Google API key revoked or rotated; model deprecated or not enabled for the key; baseUrl wrong or missing the model path; content safety filters rejecting the memory extraction prompt; free-tier quota exhausted.

Related errors


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/5bf05b96bf4515b6. Report an issue: GitHub.