{"record":{"id":"313fb938559836ad","repo":"MemPalace/mempalace","slug":"http-e-code-from-url-detail-or-e-reason","errorCode":null,"errorMessage":"HTTP {e.code} from {url}: {detail or e.reason}","messagePattern":"HTTP (.+?) from (.+?): (.+?)","errorType":"exception","errorClass":"LLMError","httpStatus":null,"severity":"error","filePath":"mempalace/llm_client.py","lineNumber":195,"sourceCode":"\n\ndef _http_post_json(url: str, body: dict, headers: dict, timeout: int) -> dict:\n    \"\"\"POST JSON and return the parsed response. Raises LLMError on any failure.\"\"\"\n    req = Request(\n        url,\n        data=json.dumps(body).encode(\"utf-8\"),\n        headers={\"Content-Type\": \"application/json\", **headers},\n    )\n    try:\n        with urlopen(req, timeout=timeout) as resp:\n            return json.loads(resp.read())\n    except HTTPError as e:\n        detail = \"\"\n        try:\n            detail = e.read().decode(\"utf-8\", errors=\"replace\")[:500]\n        except Exception:\n            pass\n        raise LLMError(f\"HTTP {e.code} from {url}: {detail or e.reason}\") from e\n    except (URLError, OSError) as e:\n        raise LLMError(f\"Cannot reach {url}: {e}\") from e\n    except json.JSONDecodeError as e:\n        raise LLMError(f\"Malformed response from {url}: {e}\") from e\n\n\n# ==================== OLLAMA ====================\n\n\nclass OllamaProvider(LLMProvider):\n    name = \"ollama\"\n    DEFAULT_ENDPOINT = \"http://localhost:11434\"\n\n    def __init__(\n        self,\n        model: str,\n        endpoint: Optional[str] = None,\n        timeout: int = 180,","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/MemPalace/mempalace/blob/06cb6987f02610784fefbad4b2bd5d026d164ba6/mempalace/llm_client.py#L177-L213","documentation":"LLMError raised by the shared _http_post_json helper when the LLM provider's HTTP endpoint returns an error status. The message includes the status code, URL, and up to 500 bytes of the response body (or the HTTP reason phrase), so auth failures, model-not-found, and rate limits are distinguishable.","triggerScenarios":"Any provider classify()/chat call where the server returns 4xx/5xx: 401/403 for a bad API key, 404 for a wrong endpoint URL or unknown model, 429 for rate limiting, 500/503 for an overloaded Ollama/vLLM/LM Studio instance.","commonSituations":"Typo in --llm-endpoint or model name; expired or missing OPENAI_API_KEY/ANTHROPIC_API_KEY; Ollama not serving the requested model (pull it first); hitting provider rate limits; local server crashed mid-request.","solutions":["Read the status code: 401/403 → fix the API key; 404 → fix endpoint URL or model name; 429 → slow down/back off; 5xx → check the local server logs","curl the endpoint directly to reproduce outside the library","For Ollama run `ollama list` / `ollama pull <model>` to confirm the model exists","Add exponential-backoff retry around 429/5xx responses"],"exampleFix":"# before\nresp = provider.classify(system, user)  # LLMError: HTTP 404 from http://localhost:11434/v1/chat/completions: model not found\n\n# after\nfrom mempalace.llm_client import LLMError\ntry:\n    resp = provider.classify(system, user)\nexcept LLMError as e:\n    if \"HTTP 4\" in str(e):\n        raise  # config problem — fix endpoint/model/key\n    raise  # or backoff-retry on 429/5xx","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"import time\nfrom mempalace.llm_client import LLMError\n\nfor attempt in range(3):\n    try:\n        return provider.classify(system, user)\n    except LLMError as e:\n        msg = str(e)\n        if \"HTTP 429\" in msg or \"HTTP 5\" in msg:\n            time.sleep(2 ** attempt)\n            continue\n        raise  # 4xx config errors are not retryable","preventionTips":["Validate endpoint, model, and API key with check_available() before batch jobs","Run `ollama list` (or provider equivalent) to confirm the model exists","Cache classification results so transient provider errors don't re-cost work"],"tags":["network","http","llm","api","configuration"],"backgroundTag":null,"analyzedSha":"06cb6987f02610784fefbad4b2bd5d026d164ba6","analyzedAt":"2026-08-15T03:03:36.213Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}