nexu-io/open-design · error · Error
openai ${resp.status}: ${await resp.text().catch(() => '')}
Error message
openai ${resp.status}: ${await resp.text().catch(() => '')} What it means
The OpenAI Chat Completions API returned a non-2xx HTTP status during the memory-LLM extraction call. The error includes the status code and raw response body. This is the callOpenAI path in the daemon's automatic memory extractor.
Source
Thrown at apps/daemon/src/memory-llm.ts:847
? { 'APP-Code': AIHUBMIX_APP_CODE }
: {}),
},
body: JSON.stringify({
model: provider.model,
response_format: { type: 'json_object' },
messages: [
{ role: 'system', content: system },
{ role: 'user', content: user },
],
}),
signal: withTimeout(FETCH_TIMEOUT_MS),
},
);
} catch (err) {
throw new Error(describeFetchError(err));
}
if (!resp.ok) {
throw new Error(`openai ${resp.status}: ${await resp.text().catch(() => '')}`);
}
const json = await resp.json();
return json?.choices?.[0]?.message?.content ?? '';
}
// Azure OpenAI speaks the same chat-completions JSON as OpenAI, but on
// a per-deployment URL and with `api-key:` instead of `Authorization:`.
// `provider.model` here is the Azure deployment name (the user typed it
// into the model field — that's what the chat picker calls "Deployment
// (Model)" too), not the underlying model family.
async function callAzure(provider, system, user) {
const base = String(provider.baseUrl || '').replace(/\/+$/, '');
const deployment = encodeURIComponent(provider.model);
const apiVersion = encodeURIComponent(
provider.apiVersion || PROVIDER_DEFAULTS.azure.apiVersion,
);
const url = `${base}/openai/deployments/${deployment}/chat/completions?api-version=${apiVersion}`;
let resp;View on GitHub (pinned to 5be4028344)
Solutions
- Check the API key is valid and has quota
- Verify provider.model is a model available on the account
- Confirm provider.baseUrl points to the correct OpenAI-compatible endpoint with /chat/completions path
- Inspect the response body for the specific error code
- Retry after a delay if rate-limited (429)
Defensive patterns
Strategy: try-catch
Try / catch
try {
const text = await callOpenAI(provider, system, user);
} catch (err) {
if (err.message.startsWith('openai ')) {
const status = parseInt(err.message.split(' ')[1], 10);
if (status === 429) {
await sleep(backoffMs);
return callOpenAI(provider, system, user);
}
if (status === 401 || status === 403) {
throw new Error('OpenAI API key is invalid or lacks permission');
}
}
throw err;
} Prevention
- Verify the OpenAI API key and organization billing status
- Confirm provider.model is an available model identifier
- Ensure provider.baseUrl includes the correct /chat/completions path or base origin
- Handle 429 responses with exponential backoff
When it happens
Trigger: Invalid or expired API key (401/403); rate limiting (429); model name not available; quota exceeded; malformed request payload; baseUrl pointing to a wrong endpoint.
Common situations: API key rotated without updating config; wrong baseUrl (e.g. pointing to Azure endpoint without the OpenAI path); model deprecated; hitting rate limits during batch extraction; organization billing issues.
Related errors
- azure ${resp.status}: ${await resp.text().catch(() => '')}
- anthropic ${resp.status}: ${await resp.text().catch(() => ''
- google ${resp.status}: ${await resp.text().catch(() => '')}
- collab cloud error ${status} (${code})
- elevenlabs voices ${resp.status}: ${errText.slice(0, 240)}
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/96c6b6b03177cde5.
Report an issue: GitHub.