{"record":{"id":"dc7a12d14a9edd5c","repo":"Fosowl/agenticSeek","slug":"invalid-json-from-lm-studio-response-text-200","errorCode":null,"errorMessage":"Invalid JSON from LM Studio: {response.text[:200]}","messagePattern":"Invalid JSON from LM Studio: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"sources/llm_provider.py","lineNumber":393,"sourceCode":"            url = addr\n        route_start = f\"{url}/v1/chat/completions\"\n        payload = {\n            \"messages\": history,\n            \"temperature\": 0.7,\n            \"max_tokens\": 4096,\n            \"model\": self.model\n        }\n\n        try:\n            response = requests.post(route_start, json=payload, timeout=30)\n            if response.status_code != 200:\n                raise Exception(f\"LM Studio returned status {response.status_code}: {response.text}\")\n            if not response.text.strip():\n                raise Exception(\"LM Studio returned empty response\")\n            try:\n                result = response.json()\n            except ValueError as json_err:\n                raise Exception(f\"Invalid JSON from LM Studio: {response.text[:200]}\") from json_err\n\n            if verbose:\n                print(\"Response from LM Studio:\", result)\n            choices = result.get(\"choices\", [])\n            if not choices:\n                raise Exception(f\"No choices in LM Studio response: {result}\")\n\n            message = choices[0].get(\"message\", {})\n            content = message.get(\"content\", \"\")\n            if not content:\n                raise Exception(f\"Empty content in LM Studio response: {result}\")\n            return content\n\n        except requests.exceptions.Timeout:\n            raise Exception(\"LM Studio request timed out - check if server is responsive\")\n        except requests.exceptions.ConnectionError:\n            raise Exception(f\"Cannot connect to LM Studio at {route_start} - check if server is running\")\n        except requests.exceptions.RequestException as e:","sourceCodeStart":375,"sourceCodeEnd":411,"githubUrl":"https://github.com/Fosowl/agenticSeek/blob/ae57a2357745a9706cb12d0fd76d954c84d166fa/sources/llm_provider.py#L375-L411","documentation":"lm_studio_fn calls response.json() inside a try and, on ValueError (invalid JSON), raises this message including the first 200 chars of the raw body. It means LM Studio returned non-JSON content with a 200 status — often an HTML error page or truncated output.","triggerScenarios":"response.json() raises ValueError: body is HTML (server error page), truncated streaming output, or binary/garbage instead of the expected OpenAI-compatible JSON.","commonSituations":"An intermediate proxy or auth captive portal returning HTML with 200; LM Studio serving a partial body after crash; pointing route_start at a wrong endpoint (e.g. the web UI) instead of /v1/chat/completions.","solutions":["Inspect the 200-char body in the message — HTML indicates you're hitting the wrong endpoint or a portal","Verify route_start points at the OpenAI-compatible endpoint (http://<host>:1234/v1/chat/completions)","Print the full raw response (curl the same URL) to see the complete non-JSON payload","Restart LM Studio server and retry to rule out a truncated response","Update LM Studio; ensure Content-Type application/json is sent (the library does this)"],"exampleFix":"// before\nurl = \"http://localhost:1234\"  # web UI, returns HTML\n// after\nurl = \"http://localhost:1234/v1/chat/completions\"","handlingStrategy":"type-guard","validationCode":"def assert_chat_completions_url(url):\n    assert url.rstrip('/').endswith('/v1/chat/completions'), f\"'{url}' is not the chat completions endpoint\"","typeGuard":"def is_json_object(text: str):\n    import json\n    try:\n        obj = json.loads(text)\n        return obj if isinstance(obj, dict) else None\n    except json.JSONDecodeError:\n        return None","tryCatchPattern":"try:\n    content = provider.lm_studio_fn(history)\nexcept Exception as e:\n    if \"Invalid JSON from LM Studio\" in str(e):\n        body = str(e).split(\": \", 1)[-1]\n        if body.lstrip().startswith(\"<\"):\n            fix_endpoint_url()  # HTML => wrong endpoint or portal\n        else:\n            restart_server_and_retry()\n    else:\n        raise","preventionTips":["Always point at /v1/chat/completions, not the LM Studio web UI port path","Inspect the embedded 200-char body in the message before debugging blind","curl the endpoint once at startup to confirm JSON responses","Keep proxies/portals out of the local loopback path"],"tags":["lm-studio","json","parsing","local-server"],"backgroundTag":"invalid-json-response","analyzedSha":"ae57a2357745a9706cb12d0fd76d954c84d166fa","analyzedAt":"2026-08-30T02:49:05.834Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}