{"record":{"id":"062bc65a045cf082","repo":"gitbutlerapp/gitbutler","slug":"lm-studio-api-error-response-status-errortext","errorCode":null,"errorMessage":"LM Studio API error (${response.status}): ${errorText}","messagePattern":"LM Studio API error \\((.+?)\\): (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/desktop/src/lib/ai/lmStudioClient.ts","lineNumber":69,"sourceCode":"\n\t\t\t// Make request to the LM Studio API\n\t\t\tconst response = await fetch(`${this.baseUrl}/chat/completions`, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tmodel: this.modelName,\n\t\t\t\t\tmessages: messages,\n\t\t\t\t\ttemperature: DEFAULT_TEMPERATURE,\n\t\t\t\t\tmax_tokens: options?.maxTokens ?? DEFAULT_MAX_TOKENS,\n\t\t\t\t\tstream: shouldStream,\n\t\t\t\t}),\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tconst errorText = await response.text();\n\t\t\t\tthrow new Error(`LM Studio API error (${response.status}): ${errorText}`);\n\t\t\t}\n\n\t\t\t// Handle streaming response\n\t\t\tif (shouldStream) {\n\t\t\t\tconst reader = response.body?.getReader();\n\t\t\t\tif (!reader) {\n\t\t\t\t\tthrow new Error(\"Failed to get reader from response\");\n\t\t\t\t}\n\n\t\t\t\tlet result = \"\";\n\t\t\t\tconst decoder = new TextDecoder();\n\n\t\t\t\twhile (true) {\n\t\t\t\t\tconst { done, value } = await reader.read();\n\t\t\t\t\tif (done) break;\n\n\t\t\t\t\tconst chunk = decoder.decode(value, { stream: true });\n\t\t\t\t\tconst lines = chunk","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/apps/desktop/src/lib/ai/lmStudioClient.ts#L51-L87","documentation":"After POSTing to the LM Studio chat completions endpoint, a non-2xx HTTP status triggers this error, embedding the status code and the raw response body. It means LM Studio (or the proxy) rejected the request server-side.","triggerScenarios":"The fetch to {endpoint}/chat/completions resolves but response.ok is false — e.g. 404 because the model name is wrong, 400 for a malformed payload, 500 when the local server errors.","commonSituations":"Model not loaded in LM Studio or wrong model name; LM Studio server returning 404 because the endpoint URL includes/omits /v1 incorrectly; requesting an unavailable context length; server overloaded or crashed mid-request.","solutions":["Read the errorText in the message for the server's reason and fix the request accordingly.","Verify the model name matches a loaded model in LM Studio.","Confirm the endpoint URL points at LM Studio's OpenAI-compatible API (typically http://localhost:1234/v1).","Check LM Studio server logs for the corresponding error."],"exampleFix":"// before\nconst client = new LMStudioClient('http://localhost:1234', 'mistral-7b');\n// after (include /v1 base and a loaded model id)\nconst client = new LMStudioClient('http://localhost:1234/v1', 'mistral-7b-instruct-v0.2');","handlingStrategy":"try-catch","validationCode":"const health = await fetch(endpoint + '/models');\nif (!health.ok) throw new Error(`LM Studio endpoint unhealthy: ${health.status}`);","typeGuard":null,"tryCatchPattern":"try {\n  await client.evaluate(prompt);\n} catch (e) {\n  const m = e.message.match(/LM Studio API error \\((\\d+)\\): (.*)/s);\n  if (m) {\n    const [_, status, body] = m;\n    // handle 404 (wrong model/endpoint), 400 (bad payload), 5xx (server error)\n  } else {\n    throw e;\n  }\n}","preventionTips":["Verify the model name matches a model loaded in LM Studio before calling.","Use the full OpenAI-compatible base URL including /v1.","Check the LM Studio server log when upgrading versions."],"tags":["http","api","lm-studio"],"backgroundTag":"http-error-response","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}