{"record":{"id":"b256b90eeea06621","repo":"danielmiessler/Fabric","slug":"http-error","errorCode":"HTTP_ERROR","errorMessage":"HTTP error! status: ${response.status}","messagePattern":"HTTP error! status: (.+?)","errorType":"exception","errorClass":"ChatError","httpStatus":null,"severity":"error","filePath":"web/src/lib/services/ChatService.ts","lineNumber":70,"sourceCode":"\t\t\t\tlanguage: get(languageStore),\n\t\t\t\tpattern: get(selectedPatternName),\n\t\t\t\tpromptCount: request.prompts?.length,\n\t\t\t\tmessageCount: request.messages?.length,\n\t\t\t});\n\t\t\t// NEW: Log the full payload before sending to backend\n\t\t\tconsole.log(\n\t\t\t\t\"Final ChatRequest payload:\",\n\t\t\t\tJSON.stringify(request, null, 2),\n\t\t\t);\n\n\t\t\tconst response = await fetch(\"/api/chat\", {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\tbody: JSON.stringify(request),\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new ChatError(\n\t\t\t\t\t`HTTP error! status: ${response.status}`,\n\t\t\t\t\t\"HTTP_ERROR\",\n\t\t\t\t\t{ status: response.status },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst reader = response.body?.getReader();\n\t\t\tif (!reader) {\n\t\t\t\tthrow new ChatError(\"Response body is null\", \"NULL_RESPONSE\");\n\t\t\t}\n\n\t\t\treturn this.createMessageStream(reader);\n\t\t} catch (error) {\n\t\t\tif (error instanceof ChatError) throw error;\n\t\t\tthrow new ChatError(\"Failed to fetch chat stream\", \"FETCH_ERROR\", error);\n\t\t}\n\t}\n","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/danielmiessler/Fabric/blob/338b89cfe97ab2d12ce30ce8b5449857a841366d/web/src/lib/services/ChatService.ts#L52-L88","documentation":"ChatService.sendMessage throws ChatError('HTTP error! status: N', 'HTTP_ERROR') when POST /api/chat returns non-2xx before streaming begins. The logged 'Final ChatRequest payload' immediately above is the exact body that was rejected, which is the key debugging artifact.","triggerScenarios":"POST /api/chat with a request referencing an unknown pattern/model/vendor (400/404), backend LLM provider unreachable (5xx), or malformed request JSON the chat handler rejects.","commonSituations":"Pattern renamed or missing server-side; selected model no longer available (Ollama model pulled); API key for the vendor missing server-side; backend upgraded with breaking request-schema changes while the frontend is stale.","solutions":["Open devtools Network tab, take the logged 'Final ChatRequest payload', and replay it with curl to see the server's error body","Verify every field of the request (pattern, model, vendor) exists server-side","Fix the server-side cause (restore pattern, re-pull model, set API key)"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"const models = await modelsApi.getAvailable();\nif (!models.some(m => m.name === request.model && m.vendor === request.vendor)) {\n  throw new Error(`Model ${request.vendor}/${request.model} is not available`);\n}","typeGuard":"function isChatHttpError(e: unknown): e is ChatError & { code: 'HTTP_ERROR' } {\n  return e instanceof ChatError && e.code === 'HTTP_ERROR';\n}","tryCatchPattern":"try { stream = await chatService.sendMessage(request); }\ncatch (e) {\n  if (isChatHttpError(e)) {\n    const status = (e.details as any)?.status;\n    if (status === 404 || status === 400) showUserFixableMessage(); // bad pattern/model\n    else showServerError();\n  } else throw e;\n}","preventionTips":["Validate pattern/model/vendor against the fetched model list before sending","Match frontend request schema to the backend's current /api/chat contract"],"tags":["http","chat","streaming","api-client"],"backgroundTag":null,"analyzedSha":"338b89cfe97ab2d12ce30ce8b5449857a841366d","analyzedAt":"2026-08-15T11:38:51.759Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}