{"record":{"id":"d3a736a301ef405e","repo":"affaan-m/ECC","slug":"msg-d3a736","errorCode":null,"errorMessage":"{msg}","messagePattern":"\\{msg\\}","errorType":"exception","errorClass":"AuthenticationError","httpStatus":401,"severity":"error","filePath":"src/llm/providers/atlas.py","lineNumber":133,"sourceCode":"            usage = None\n            if response.usage:\n                usage = {\n                    \"prompt_tokens\": response.usage.prompt_tokens,\n                    \"completion_tokens\": response.usage.completion_tokens,\n                    \"total_tokens\": response.usage.total_tokens,\n                }\n\n            return LLMOutput(\n                content=choice.message.content or \"\",\n                tool_calls=tool_calls,\n                model=response.model,\n                usage=usage,\n                stop_reason=choice.finish_reason,\n            )\n        except Exception as e:\n            msg = str(e)\n            if \"401\" in msg or \"authentication\" in msg.lower():\n                raise AuthenticationError(msg, provider=self.provider_type) from e\n            if \"429\" in msg or \"rate_limit\" in msg.lower():\n                raise RateLimitError(msg, provider=self.provider_type) from e\n            if \"context\" in msg.lower() and \"length\" in msg.lower():\n                raise ContextLengthError(msg, provider=self.provider_type) from e\n            raise\n\n    def list_models(self) -> list[ModelInfo]:\n        return self._models.copy()\n\n    def validate_config(self) -> bool:\n        return bool(self.api_key)\n\n    def get_default_model(self) -> str:\n        return self.default_model\n","sourceCodeStart":115,"sourceCodeEnd":148,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/src/llm/providers/atlas.py#L115-L148","documentation":"AtlasProvider.generate() wraps an OpenAI-compatible call to the Atlas reasoning-model gateway. Line 133 re-raises the caught exception as llm.core.interface.RateLimitError (tagged with the Atlas provider) when the exception's stringified message contains '429' or 'rate_limit'. The match is naive substring detection on str(e), so it only fires if the SDK surfaces the HTTP status or the literal token 'rate_limit' in its message text. Atlas reasoning models also reserve a thinking-token budget, which can push a request over TPM limits faster than the raw prompt suggests.","triggerScenarios":"Calling AtlasProvider.generate() when the Atlas endpoint responds HTTP 429 Too Many Requests; the openai SDK raising an error whose str() contains '429' or 'rate_limit' (e.g. openai.RateLimitError); exceeding the per-minute RPM or TPM quota on the Atlas gateway.","commonSituations":"Bursting past the Atlas gateway RPM/TPM quota; a shared org key used by multiple concurrent jobs; CI/load-test runs hammering the reasoning endpoint; thinking-token budget inflating billable TPM.","solutions":["Wrap generate() in exponential backoff keyed on llm.core.interface.RateLimitError and retry.","Throttle concurrent generate() calls per Atlas API key with a semaphore.","Verify the Atlas key tier/quota and request an increase if sustained throughput is needed.","Reduce prompt size or fan-out so total tokens-per-minute stays under the limit."],"exampleFix":"// before\noutput = provider.generate(llm_input)\n\n// after\nimport time\nfrom llm.core.interface import RateLimitError\n\nfor attempt in range(4):\n    try:\n        output = provider.generate(llm_input)\n        break\n    except RateLimitError:\n        if attempt == 3:\n            raise\n        time.sleep(2 ** attempt)","handlingStrategy":"retry","validationCode":null,"typeGuard":"from llm.core.interface import RateLimitError\n\ndef is_rate_limit(exc: BaseException) -> bool:\n    return isinstance(exc, RateLimitError)","tryCatchPattern":"import time\nfrom llm.core.interface import RateLimitError\n\nfor attempt in range(4):\n    try:\n        output = provider.generate(llm_input)\n        break\n    except RateLimitError:\n        if attempt == 3:\n            raise\n        time.sleep(2 ** attempt)","preventionTips":["Throttle concurrent generate() calls per Atlas key with a semaphore.","Catch llm.core.interface.RateLimitError specifically and back off, not generic Exception.","Instrument 429 counts per key to spot quota pressure early.","Account for the Atlas thinking-token budget when estimating TPM usage."],"tags":["atlas","rate-limit","llm-provider","retry","quota"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}