{"record":{"id":"bdefd7ff9075b7fc","repo":"affaan-m/ECC","slug":"ratelimiterror-msg-provider-providertype-openai-from-e","errorCode":null,"errorMessage":"RateLimitError(msg, provider=ProviderType.OPENAI) from e","messagePattern":"RateLimitError\\(msg, provider=ProviderType\\.OPENAI\\) from e","errorType":"exception","errorClass":"RateLimitError","httpStatus":null,"severity":"error","filePath":"src/llm/providers/openai.py","lineNumber":119,"sourceCode":"                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=ProviderType.OPENAI) from e\n            if \"429\" in msg or \"rate_limit\" in msg.lower():\n                raise RateLimitError(msg, provider=ProviderType.OPENAI) from e\n            if \"context\" in msg.lower() and \"length\" in msg.lower():\n                raise ContextLengthError(msg, provider=ProviderType.OPENAI) 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.client.api_key)\n\n    def get_default_model(self) -> str:\n        return \"gpt-4o-mini\"\n","sourceCodeStart":101,"sourceCodeEnd":132,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/src/llm/providers/openai.py#L101-L132","documentation":"The OpenAI provider raises RateLimitError when the API error message contains '429' or 'rate_limit'. It indicates the request was throttled — org rate limits, token-per-minute limits, or insufficient quota — and the original exception is chained.","triggerScenarios":"Calling generate() faster than your org's RPM/TPM limits; hitting usage-tier caps; a burst of parallel requests on a low-tier key.","commonSituations":"Fan-out loops over many prompts; new accounts on tier 1 with tiny TPM limits; shared org keys consumed by multiple services; monthly quota exhausted.","solutions":["Retry with exponential backoff and jitter honoring the Retry-After header","Batch/serialize requests to stay under RPM/TPM limits","Request a rate-limit tier increase or add billing credit","Check usage and limits at platform.openai.com/usage"],"exampleFix":"// before\nfor item in items:\n    results.append(provider.generate(inp(item)))\n// after\nfor item in items:\n    try:\n        results.append(provider.generate(inp(item)))\n    except RateLimitError:\n        time.sleep(1); results.append(provider.generate(inp(item)))","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    resp = provider.generate(inp)\nexcept RateLimitError as e:\n    delay = getattr(e.__cause__, \"retry_after\", 2)\n    time.sleep(delay)\n    resp = provider.generate(inp)","preventionTips":["Respect TPM/RPM limits and pace requests","Use exponential backoff with jitter on 429s","Upgrade usage tier or request higher limits","Centralize a shared limiter across services using the same key"],"tags":["openai","rate-limit","throttling"],"backgroundTag":"rate-limit-exceeded","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}