{"record":{"id":"1a0c4ba88be5c19d","repo":"BerriAI/litellm","slug":"response-from-posthog-api-status-code-response-s","errorCode":null,"errorMessage":"Response from PostHog API status_code: {response.status_code}, text: {response.text}","messagePattern":"Response from PostHog API status_code: (.+?), text: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"warning","filePath":"litellm/integrations/posthog.py","lineNumber":102,"sourceCode":"                raise Exception(\"PostHog credentials not found in kwargs\")\n            event_payload: Final = self.create_posthog_event_payload(kwargs)\n\n            headers: Final = {\n                \"Content-Type\": \"application/json\",\n            }\n\n            payload: Final = self._create_posthog_payload([event_payload], api_key)\n            capture_url: Final = f\"{api_url.rstrip('/')}/batch/\"\n\n            response: Final = self.sync_client.post(\n                url=capture_url,\n                content=safe_dumps(payload),\n                headers=headers,\n            )\n            response.raise_for_status()\n\n            if response.status_code != 200:\n                raise Exception(f\"Response from PostHog API status_code: {response.status_code}, text: {response.text}\")\n\n            if self.is_mock_mode:\n                verbose_logger.debug(\"[POSTHOG MOCK] Sync event successfully mocked\")\n            else:\n                verbose_logger.debug(\"PostHog: Sync event successfully sent\")\n\n        except Exception as e:\n            verbose_logger.exception(\"PostHog Sync Layer Error - %s\", e)\n\n    async def async_log_success_event(self, kwargs, response_obj, start_time, end_time):\n        try:\n            verbose_logger.debug(\"PostHog: Async logging - Enters logging function for model %s\", kwargs)\n            self._ensure_async_setup()  # Lazy initialization\n            await self._log_async_event(kwargs, response_obj, start_time, end_time)\n        except Exception as e:\n            verbose_logger.exception(\"PostHog Layer Error - %s\", e)\n\n    async def async_log_failure_event(self, kwargs, response_obj, start_time, end_time):","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/integrations/posthog.py#L84-L120","documentation":"After POSTing a single event to {POSTHOG_API_URL}/batch/, the sync PostHog logger raises this if the final status is anything other than 200. Because response.raise_for_status() runs first, genuine 4xx/5xx surface as httpx.HTTPStatusError — this custom message only fires for statuses raise_for_status tolerates: 201/202/204-style codes and 3xx redirects (httpx does not follow redirects by default). The enclosing except logs it with verbose_logger.exception, so the telemetry event is dropped but the LLM call succeeds.","triggerScenarios":"POSTHOG_API_URL using http:// where the server answers the /batch/ POST with a 301/302 redirect to https; a self-hosted PostHog or an intermediary gateway returning 2xx-but-not-200 (201/202/204); the URL pointing at a non-PostHog service that replies with an odd success code.","commonSituations":"Region mismatch (us vs eu host), trailing path segments in POSTHOG_API_URL, corporate proxies rewriting responses, PostHog cloud incidents returning unusual statuses.","solutions":["Set POSTHOG_API_URL to the exact region root with https (e.g. https://us.i.posthog.com or https://eu.i.posthog.com), no trailing path","Reproduce with curl -X POST '{url}/batch/' -H 'Content-Type: application/json' -d '<sample batch>' and inspect status plus body","Enable debug logging (set litellm verbose / LITELLM_LOG=DEBUG) to capture the exact status_code/text pair reported in the message","If an intermediary returns non-200 success codes or redirects, exempt the PostHog host from rewriting or follow redirects yourself"],"exampleFix":"# before\nos.environ['POSTHOG_API_URL'] = 'http://app.posthog.com'  # 301 -> non-200 -> exception in logs\n\n# after\nos.environ['POSTHOG_API_URL'] = 'https://us.i.posthog.com'  # matches your project region","handlingStrategy":"validation","validationCode":"import httpx, os\n\nurl = os.getenv('POSTHOG_API_URL', 'https://us.i.posthog.com').rstrip('/')\nresp = httpx.post(f'{url}/batch/', json={'api_key': os.environ['POSTHOG_API_KEY'], 'batch': [], 'historical_migration': False})\nif resp.status_code != 200:\n    raise RuntimeError(f'PostHog preflight failed: {resp.status_code} {resp.text}')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use the exact https region root for POSTHOG_API_URL to avoid 3xx redirects on the batch POST","Run a batch-endpoint smoke test at startup before trusting telemetry","Monitor verbose_logger output for dropped events — failures are non-blocking by design"],"tags":["posthog","telemetry","http-status","callback","redirect"],"backgroundTag":"http-error-response","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}