BerriAI/litellm · error · ValueError
Cannot route sensitive data without a session_id. Ensure…
Error message
Cannot route sensitive data without a session_id. Ensure the request includes a session_id in metadata or headers.
What it means
For sensitive-data rerouting, CustomGuardrail.raise_sensitive_data_route_exception() must bind the flagged request to a sticky session on the alternate model. It first extracts a session id from the request data via get_session_id_from_request_data (metadata.session_id or the session headers); when none is found it raises this ValueError before the rerouting SensitiveDataRouteException is ever raised.
Solutions
- Send metadata={'session_id': '<stable id>'} (or the proxy's session header) on every request that may carry sensitive data
- Fix header/metadata propagation through your gateway so the session id survives to the guardrail
- If traffic is genuinely sessionless, disable sensitive-data routing and use plain blocking/masking mode
Example fix
# before
response = litellm.acompletion(model='gpt-4o', messages=[...]) # no session id -> ValueError on detection
# after
response = litellm.acompletion(
model='gpt-4o', messages=[...],
metadata={'session_id': user_conversation_id}, # enables sticky rerouting
) Defensive patterns
Strategy: validation
Validate before calling
sid = request_data.get('metadata', {}).get('session_id')
if not sid:
raise HTTPException(400, 'session_id required when sensitive-data routing is enabled')
await guardrail.raise_sensitive_data_route_exception(route_to_model, request_data, detection_info) Type guard
def has_session_id(request_data: dict) -> bool:
meta = request_data.get('metadata') or {}
return bool(meta.get('session_id')) or bool(request_data.get('headers')) Try / catch
except ValueError as e:
if 'session_id' in str(e):
retry the call once after attaching metadata={'session_id': str(uuid4())}
else:
raise Prevention
- Propagate a stable session_id in metadata for every conversation
- Ensure gateways forward custom session headers
- Reject sessionless requests early when routing mode is on
When it happens
Trigger: Guardrail configured with sensitive_data_route_to_model and a request arrives without metadata['session_id'] and without a session header; direct SDK/API calls into the proxy that never established a session; session field name typos like 'sessionId' in metadata.
Common situations: Enabling sensitive-data routing on an existing traffic stream that does not yet propagate session ids; clients migrated from raw completions calls with no session concept; gateway stripping custom headers including the session one.
Related errors
- Sensitive data detected by
- Sensitive data detected by
- CodeInterpreterInterception: no sandbox available. Provide…
- Event hook is not in the supported event hooks
- Event hook is not in the supported event hooks
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/3fbb8c9d1474bcff.
Report an issue: GitHub.
Appendix: source
Thrown at litellm/integrations/custom_guardrail.py:277
to route to an on-premise model instead of blocking.
The exception will reroute this request to the specified model. When
sticky_session_routing is enabled (the default), it also stores the
routing decision so subsequent requests in this session reuse the model.
Args:
route_to_model: The model to route this request (and session) to
request_data: The original request data dictionary
detection_info: Optional non-sensitive detection metadata (e.g. matched
entity types, rule ids, scores). This is surfaced in request metadata
and logs, so it must not contain the raw detected sensitive values.
Raises:
SensitiveDataRouteException: Always raises to trigger rerouting
"""
session_id: Final = self._get_session_id_from_request_data(request_data)
if not session_id:
raise ValueError(
"Cannot route sensitive data without a session_id. "
"Ensure the request includes a session_id in metadata or headers."
)
raise SensitiveDataRouteException(
route_to_model=route_to_model,
session_id=session_id,
guardrail_name=self.guardrail_name,
detection_info=detection_info,
sticky_session_routing=self.sticky_session_routing,
)
def _get_session_id_from_request_data(self, request_data: dict[str, Any]) -> str | None:
"""Extract session_id from request data."""
return get_session_id_from_request_data(request_data)
@staticmethod
def _scanned_text_hash(text: str) -> str:View on GitHub (pinned to 77b7c6c40c)