mudler/LocalAI · error · Error
HTTP ${response.status}
Error message
HTTP ${response.status} What it means
Thrown by useChat.js when the legacy MCP SSE streaming POST to the /v1/mcp/chat/completions endpoint returns a non-2xx status. The raw HTTP status/message is only the fallback — extractHttpError(response) is called first to pull a structured error message out of the response body, so the thrown Error usually carries the server's own message (e.g. 'model not found'). This is the chat-modality request path for MCP tool-driven conversations.
Source
Thrown at core/http/react-ui/src/hooks/useChat.js:372
maxTpsRef.current = 0
let usage = {}
const newMessages = [] // Accumulate messages to add to history
if (activeChat.mcpMode && !hasMcpServers) {
// Legacy MCP SSE streaming (custom event types from /v1/mcp/chat/completions)
try {
const timeoutId = setTimeout(() => controller.abort(), 300000) // 5 min timeout
const response = await fetch(apiUrl(endpoint), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(requestBody),
signal: controller.signal,
})
clearTimeout(timeoutId)
if (!response.ok) {
throw new Error(await extractHttpError(response))
}
const reader = response.body.pipeThrough(new TextDecoderStream()).getReader()
let buffer = ''
let assistantContent = ''
let reasoningContent = ''
let hasReasoningFromAPI = false
let currentToolCalls = []
while (true) {
const { value, done } = await reader.read()
if (done) break
buffer += value
const lines = buffer.split('\n')
buffer = lines.pop() || ''
for (const line of lines) {View on GitHub (pinned to 44413a9d06)
Solutions
- Read the actual message: the Error text is extracted from the response JSON (extractHttpError), which names the real cause — act on that first
- Verify the model exists and is loaded: GET /v1/models in the same UI, and pull/load it if absent
- Check auth: if the server runs with an API key, configure it in the UI settings so the request carries it
- Confirm the LocalAI version serves /v1/mcp/chat/completions (legacy path) — upgrade or switch to the non-legacy streaming path if not
Example fix
// before
if (!response.ok) {
throw new Error(await extractHttpError(response))
}
// after — the throw already extracts the server message; surface it fully to the user
catch (err) {
setError(err.message || `HTTP request failed`)
addToast(err.message, 'error')
} Defensive patterns
Strategy: try-catch
Validate before calling
// verify model availability before opening the SSE stream
const models = await modelsApi.listV1()
if (!models.data?.some((m) => m.id === requestBody.model)) throw new Error(`unknown model ${requestBody.model}`) Try / catch
try {
const response = await fetch(apiUrl(endpoint), ...)
if (!response.ok) throw new Error(await extractHttpError(response))
} catch (err) {
if (err.name === 'AbortError') setError('request timed out')
else setError(err.message)
} Prevention
- Pre-check the model is loaded via GET /v1/models before starting an MCP chat
- Keep the UI's API key setting in sync with the server's auth requirement
- Distinguish AbortError (5-min timeout) from HTTP errors in the catch
When it happens
Trigger: POSTing a chat completion with MCP tools attached to /v1/mcp/chat/completions where the server rejects it: unknown model name in the request body, model not loaded, missing/invalid auth for the endpoint, or a backend error during tool execution. The 5-minute abort timer (setTimeout controller.abort 300000) can also surface here as an AbortError, but the HTTP error path is specifically a non-ok status.
Common situations: Model name typo or model not pulled/loaded in LocalAI; API key required by the server but not configured in the UI; backend crash mid-request; hitting an older LocalAI build that lacks the /v1/mcp endpoint; CORS/proxy returning 502 in front of LocalAI.
Related errors
- HTTP ${response.status}
- HTTP ${r.status}
- HTTP ${response.status}
- status: HTTP ${statusRes.status}
- HTTP ${response.status}
AI-assisted analysis of mudler/LocalAI@44413a9d06 (2026-08-15).
Data as JSON: /api/errors/90ec7dbbd577c315.
Report an issue: GitHub.