{"record":{"id":"9f4e27790c3a8de8","repo":"BerriAI/litellm","slug":"sensitive-data-detected-by-self-guardrail-name","errorCode":null,"errorMessage":"Sensitive data detected by {self.guardrail_name} (routing skipped: request has no session_id)","messagePattern":"Sensitive data detected by (.+?) \\(routing skipped: request has no session_id\\)","errorType":"exception","errorClass":"GuardrailRaisedException","httpStatus":null,"severity":"error","filePath":"litellm/integrations/custom_guardrail.py","lineNumber":424,"sourceCode":"            request_data: The request data dictionary\n            detection_info: Optional non-sensitive detection metadata. When routing,\n                this is surfaced in request metadata and logs, so it must not contain\n                the raw detected sensitive values.\n\n        Raises:\n            SensitiveDataRouteException: When configured to route and a session_id is present\n            GuardrailRaisedException: When configured to block, or when routing is\n                configured but no session_id is available\n        \"\"\"\n        if self.should_route_on_sensitive_data():\n            try:\n                self.raise_sensitive_data_route_exception(\n                    route_to_model=self.sensitive_data_route_to_model,\n                    request_data=request_data,\n                    detection_info=detection_info,\n                )\n            except ValueError:\n                raise GuardrailRaisedException(\n                    message=(\n                        f\"Sensitive data detected by {self.guardrail_name} (routing skipped: request has no session_id)\"\n                    ),\n                    guardrail_name=self.guardrail_name,\n                )\n        else:\n            raise GuardrailRaisedException(\n                message=f\"Sensitive data detected by {self.guardrail_name}\",\n                guardrail_name=self.guardrail_name,\n            )\n\n    @staticmethod\n    def get_config_model() -> type[\"GuardrailConfigModel\"] | None:\n        \"\"\"\n        Returns the config model for the guardrail\n\n        This is used to render the config model in the UI.\n        \"\"\"","sourceCodeStart":406,"sourceCodeEnd":442,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/integrations/custom_guardrail.py#L406-L442","documentation":"The guardrail is configured to reroute requests containing sensitive data (sensitive_data_route_to_model), detection fired, but the request has no session_id, so raise_sensitive_data_route_exception raised ValueError. The guardrail then downgrades routing to blocking: it raises GuardrailRaisedException with '(routing skipped: request has no session_id)', which aborts the LLM call instead of rerouting it. This is the failure mode you actually see at the proxy boundary when route-mode PII handling cannot stick the session.","triggerScenarios":"Guardrail config with mode/should_route_on_sensitive_data plus sensitive_data_route_to_model; sensitive data is detected; _get_session_id_from_request_data returns None (no session_id in metadata or headers). Typical with proxy /v1/chat/completions calls that omit session_id while the guardrail yaml has litellm_params.sensitive_data_route_to_model set.","commonSituations":"Enabling PII rerouting in proxy_config.yaml but clients (curl, LangChain, openai SDK) send no session identifier; sticky-session routing expectations after upgrading guardrail configs; testing route mode with minimal payloads.","solutions":["Send a session_id with every request through this guardrail (metadata={'session_id': ...} or the matching header) so routing can proceed instead of blocking","Verify the guardrail's _get_session_id_from_request_data lookup keys match what your client actually sends","If blocking on missing session is too strict, disable route mode (drop sensitive_data_route_to_model) and use mask mode, or catch GuardrailRaisedException upstream and retry with a session_id"],"exampleFix":"# before (client)\ncurl -X POST http://proxy:4000/v1/chat/completions \\\n  -H 'Authorization: Bearer sk-...' \\\n  -d '{\"model\": \"gpt-4o\", \"messages\": [{\"role\": \"user\", \"content\": \"...\"}]}'\n\n# after (client)\ncurl -X POST http://proxy:4000/v1/chat/completions \\\n  -H 'Authorization: Bearer sk-...' \\\n  -d '{\"model\": \"gpt-4o\", \"messages\": [{\"role\": \"user\", \"content\": \"...\"}], \"metadata\": {\"session_id\": \"sess-42\"}}'","handlingStrategy":"try-catch","validationCode":"from litellm.proxy.guardrails.guardrail_hooks import _get_session_id_from_request_data  # or replicate lookup\n\nif not _get_session_id_from_request_data(request_data):\n    request_data.setdefault(\"metadata\", {})[\"session_id\"] = str(uuid.uuid4())","typeGuard":null,"tryCatchPattern":"from litellm.integrations.custom_guardrail import GuardrailRaisedException\n\ntry:\n    resp = client.chat.completions.create(...)\nexcept (Exception,) as e:\n    if \"routing skipped: request has no session_id\" in str(e):\n        retry_with_session_id(request, str(uuid.uuid4()))\n    else:\n        raise","preventionTips":["Always populate metadata.session_id when route-mode guardrails are enabled","Add a pre_call check/middleware that rejects or annotates session-less requests before detection runs","Monitor proxy logs for 'routing skipped' to catch clients that forgot session tracking"],"tags":["guardrail","pii","routing","session","blocking"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}