{"record":{"id":"b0c7372f5a7c4b2a","repo":"Fosowl/agenticSeek","slug":"openai-api-error-str-e","errorCode":null,"errorMessage":"OpenAI API error: {str(e)}","messagePattern":"OpenAI API error: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"sources/llm_provider.py","lineNumber":249,"sourceCode":"            client = OpenAI(api_key=self.api_key, base_url=f\"{self.internal_url}:{port}\")\n        elif self.is_local:\n            client = OpenAI(api_key=self.api_key, base_url=f\"http://{base_url}\")\n        else:\n            client = OpenAI(api_key=self.api_key)\n\n        try:\n            response = client.chat.completions.create(\n                model=self.model,\n                messages=history,\n            )\n            if response is None:\n                raise Exception(\"OpenAI response is empty.\")\n            thought = response.choices[0].message.content\n            if verbose:\n                print(thought)\n            return thought\n        except Exception as e:\n            raise Exception(f\"OpenAI API error: {str(e)}\") from e\n\n    def anthropic_fn(self, history, verbose=False):\n        \"\"\"\n        Use Anthropic to generate text.\n        \"\"\"\n        from anthropic import Anthropic\n\n        client = Anthropic(api_key=self.api_key)\n        system_message = None\n        messages = []\n        for message in history:\n            clean_message = {'role': message['role'], 'content': message['content']}\n            if message['role'] == 'system':\n                system_message = message['content']\n            else:\n                messages.append(clean_message)\n\n        try:","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/Fosowl/agenticSeek/blob/ae57a2357745a9706cb12d0fd76d954c84d166fa/sources/llm_provider.py#L231-L267","documentation":"This is the catch-all wrapper in openai_fn (sources/llm_provider.py:249): every exception raised inside the try block — including the library's own 'OpenAI response is empty.' error and any OpenAI SDK exception (authentication, rate limit, bad model, timeout) — is re-raised as Exception(f\"OpenAI API error: {str(e)}\") with the original as __cause__. It means the chat completion call failed for a reason captured in the appended message.","triggerScenarios":"Any failure during client.chat.completions.create(model=self.model, messages=history): invalid/missing API key (401), unknown model name (404/not found), rate limit (429), server error (5xx), network timeout, malformed messages payload, or the internal None-response check at line 243.","commonSituations":"Expired or wrong OPENAI_API key passed as self.api_key; typo in model name (e.g. 'gpt-4o-mini' vs 'gpt-4-32k') or using a model not available to the account; quota/billing exhausted causing 429; local compatible server down or returning errors; messages containing roles/fields the API rejects.","solutions":["Read the wrapped str(e) to identify the root cause (401 auth, 404 model, 429 rate limit, 5xx server) and fix accordingly.","Verify the API key: check that self.api_key (from config/env) is valid, active, and has billing/quota available.","Validate the model name against the account's available models (GET /v1/models) and correct it in config.ini.","For 429 errors, add retry with exponential backoff around the provider call.","Inspect the cause chain (raise ... from e) — log e.__cause__ to see the original SDK exception with full details.","If pointing at a local server, confirm the server is up and OpenAI-compatible, and that base_url/port are correct."],"exampleFix":"// before\nthought = provider.openai_fn(history)\n\n// after\nimport time\nfor attempt in range(3):\n    try:\n        thought = provider.openai_fn(history)\n        break\n    except Exception as e:\n        if '429' in str(e) and attempt < 2:\n            time.sleep(2 ** attempt)\n            continue\n        raise","handlingStrategy":"try-catch","validationCode":"import os, httpx\n\ndef assert_openai_ready(api_key=None, model=\"gpt-4o-mini\"):\n    key = api_key or os.environ.get(\"OPENAI_API_KEY\")\n    if not key:\n        raise RuntimeError(\"OPENAI_API_KEY is not set\")\n    r = httpx.get(\n        \"https://api.openai.com/v1/models\",\n        headers={\"Authorization\": f\"Bearer {key}\"}, timeout=10,\n    )\n    if r.status_code == 401:\n        raise RuntimeError(\"OpenAI API key is invalid or expired\")\n    r.raise_for_status()\n    if model not in {m[\"id\"] for m in r.json()[\"data\"]}:\n        raise RuntimeError(f\"Model '{model}' is not available to this account\")","typeGuard":"def is_retryable_openai_error(err: BaseException) -> bool:\n    \"\"\"Distinguish transient (rate limit / server) errors from permanent ones.\"\"\"\n    msg = str(err).lower()\n    return any(tok in msg for tok in (\"429\", \"rate limit\", \"503\", \"502\", \"timeout\", \"overloaded\"))","tryCatchPattern":"import time\n\ndef openai_fn_with_retry(provider, history, retries=4):\n    for attempt in range(retries):\n        try:\n            return provider.openai_fn(history)\n        except Exception as e:\n            if is_retryable_openai_error(e) and attempt < retries - 1:\n                time.sleep(2 ** attempt)\n                continue\n            if \"401\" in str(e) or \"auth\" in str(e).lower():\n                raise RuntimeError(\"Fix OPENAI_API_KEY (invalid/expired).\") from e.__cause__\n            if \"404\" in str(e) or \"model\" in str(e).lower():\n                raise RuntimeError(\"Unknown model name; check /v1/models for your account.\") from e.__cause__\n            raise","preventionTips":["Validate the API key and model name at startup (GET /v1/models) instead of at first use.","Set OPENAI_API_KEY in the environment or config before constructing the provider; never hard-code keys.","Wrap provider calls in retry-with-backoff for 429/5xx/timeout errors.","Log e.__cause__ (the original SDK exception) to preserve error codes and request IDs.","Keep the openai SDK up to date; API changes between versions commonly surface as wrapped errors."],"tags":["openai","api-error","wrapped-exception","authentication","rate-limit"],"backgroundTag":"llm-api-call-failed","analyzedSha":"ae57a2357745a9706cb12d0fd76d954c84d166fa","analyzedAt":"2026-08-30T02:49:05.834Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}