{"record":{"id":"b100c0e41a6e07c9","repo":"Fosowl/agenticSeek","slug":"unexpected-error-str-e","errorCode":null,"errorMessage":"Unexpected error: {str(e)}","messagePattern":"Unexpected error: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"sources/llm_provider.py","lineNumber":416,"sourceCode":"            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:\n            raise Exception(f\"HTTP request failed: {str(e)}\") from e\n        except Exception as e:\n            if \"LM Studio\" in str(e):\n                raise  # Re-raise our custom exceptions\n            raise Exception(f\"Unexpected error: {str(e)}\") from e\n\n    def openrouter_fn(self, history, verbose=False):\n        \"\"\"\n        Use OpenRouter API to generate text.\n        \"\"\"\n        client = OpenAI(api_key=self.api_key, base_url=\"https://openrouter.ai/api/v1\")\n        if self.is_local:\n            # This case should ideally not be reached if unsafe_providers is set correctly\n            # and is_local is False in config for openrouter\n            raise Exception(\"OpenRouter is not available for local use. Change config.ini\")\n        try:\n            response = client.chat.completions.create(\n                model=self.model,\n                messages=history,\n            )\n            if response is None:\n                raise Exception(\"OpenRouter response is empty.\")\n            thought = response.choices[0].message.content","sourceCodeStart":398,"sourceCodeEnd":434,"githubUrl":"https://github.com/Fosowl/agenticSeek/blob/ae57a2357745a9706cb12d0fd76d954c84d166fa/sources/llm_provider.py#L398-L434","documentation":"The last-resort except block in lm_studio_fn: any exception whose message does not contain 'LM Studio' is re-wrapped as 'Unexpected error: <details>'. This catches failures from non-request code in the function, such as JSON parsing of the response, missing attributes, or SDK errors raised before the request-specific handlers saw them.","triggerScenarios":"lm_studio_fn raises an exception not produced by requests and not containing 'LM Studio' in its message — e.g. response.json() failing on an HTML error page, KeyError/IndexError on an unexpected response body, or an OpenAI client error.","commonSituations":"LM Studio returns an HTML error page (proxy/captive portal) instead of JSON; model name invalid so server responds with an unexpected structure; concurrent modification of the response stream; a bug in custom prompt handling code.","solutions":["Print/log the chained exception (raise ... from e preserves the cause) to see the real underlying error","Verify the configured model name exists in LM Studio's loaded models","Confirm the endpoint returns JSON (curl http://localhost:1234/v1/chat/completions)","If the response is non-JSON, check for proxy/HTML interference and bypass it","Update LM Studio to a current version if its API response shape changed"],"exampleFix":"// before\ntry:\n    result = lm_studio_fn(history)\nexcept Exception as e:\n    print(e)  # loses the chained cause\n// after\ntry:\n    result = lm_studio_fn(history)\nexcept Exception as e:\n    import traceback; traceback.print_exception(type(e), e, e.__traceback__)  # shows original cause via __cause__","handlingStrategy":"try-catch","validationCode":"def validate_lm_studio(url):\n    import requests\n    try:\n        r = requests.get(url + '/models' if url.endswith('/v1') else url.rsplit('/',1)[0] + '/models', timeout=5)\n        return r.ok and 'data' in r.json()\n    except Exception:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    out = provider.lm_studio_fn(history)\nexcept Exception as e:\n    if 'Unexpected error' in str(e) and e.__cause__:\n        log.error(\"Underlying cause: %s\", repr(e.__cause__))\n    raise","preventionTips":["Always inspect __cause__ for the real underlying failure","Validate the model name exists on the server before calling","Confirm endpoints return JSON, not HTML error pages","Keep LM Studio updated to match API response shapes"],"tags":["lm-studio","unexpected-error","error-wrapping"],"backgroundTag":"unexpected-error","analyzedSha":"ae57a2357745a9706cb12d0fd76d954c84d166fa","analyzedAt":"2026-08-30T02:49:05.834Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}