can1357/oh-my-pi · error

${response.status} ${response.statusText}

Error message

${response.status} ${response.statusText}

What it means

callApi in the extraction client throws a plain Error containing `<status> <statusText>` whenever the chat-completions POST returns a non-OK response. It is a thin surface of the provider's HTTP error; the body (which usually holds a JSON error detail) is not included.

Source

Thrown at packages/mnemopi/src/core/extraction/client.ts:124

		diag.recordFailure("cloud", lastError, "all_models_failed");
		return "";
	}

	async callApi(
		model: string,
		messages: readonly ChatMessage[],
		temperature: number,
		maxTokens: number,
		apiKey = "",
	): Promise<string> {
		const response = await this.fetchImpl(`${this.baseUrl}/chat/completions`, {
			method: "POST",
			headers: authHeader(apiKey),
			body: JSON.stringify({ model, messages, temperature, max_tokens: maxTokens }),
			signal: AbortSignal.timeout(60000),
		});
		if (!response.ok) {
			throw new Error(`${response.status} ${response.statusText}`.trim());
		}
		const data = (await response.json()) as {
			choices?: Array<{ message?: { content?: unknown } }>;
		};
		this.callCount += 1;
		const content = data.choices?.[0]?.message?.content;
		return typeof content === "string" ? content : "";
	}

	async extractFacts(messages: readonly ChatMessage[]): Promise<ExtractedFact[]> {
		let conversationText = "";
		for (let i = 0; i < messages.length; i += 1) {
			const msg = messages[i];
			if (msg === undefined) continue;
			const content = msg.content.trim();
			if (content !== "") {
				conversationText += `[${i}] [${msg.role || "unknown"}]: ${content}\n`;
			}

View on GitHub (pinned to 9690622007)

Solutions

  1. Read the status in the message: 401 → fix the API key; 404 → fix the model name; 429 → back off / reduce concurrency.
  2. Log or inspect the raw provider response body for the detailed error (capture with a wrapper fetch if needed).
  3. Retry with exponential backoff for 429/5xx; do not retry 4xx client errors.
  4. Verify base URL and network/proxy reachability for 5xx/502 statuses.

Example fix

// before
await extractor.result(prompt); // throws "429 Too Many Requests"
// after
try {
  await extractor.result(prompt);
} catch (e) {
  if (String(e.message).startsWith("429")) await Bun.sleep(5000); // then retry
  else throw e;
}
Defensive patterns

Strategy: retry

Validate before calling

const res = await fetch(url, { method: "HEAD", headers: authHeader(apiKey) });
if (!res.ok) throw new Error(`Extraction API preflight failed: ${res.status}`);

Try / catch

try {
  return await client.result(messages);
} catch (e) {
  const m = /^([45]\d\d)/.exec(String(e.message));
  if (m && (m[1] === "429" || m[1].startsWith("5"))) {
    await Bun.sleep(2000); // then retry with backoff
  }
  throw e;
}

Prevention

When it happens

Trigger: Any non-2xx from the extraction LLM API: invalid model name (404), bad/missing API key (401), rate limits (429), server errors (5xx), or an unreachable gateway returning 502.

Common situations: Misconfigured `model` string after a provider renamed a model, exhausted quota, network proxies, or transient upstream outages during batch extraction.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/9d94f4302953b7d1. Report an issue: GitHub.