{"record":{"id":"b6da38ccd0cf817d","repo":"mlflow/mlflow","slug":"sanitization-requires-an-action-llm-url-but-none-w","errorCode":null,"errorMessage":"Sanitization requires an action_llm_url but none was configured.","messagePattern":"Sanitization requires an action_llm_url but none was configured\\.","errorType":"exception","errorClass":"GuardrailViolation","httpStatus":null,"severity":"error","filePath":"mlflow/gateway/guardrails.py","lineNumber":228,"sourceCode":"        self,\n        payload: dict[str, Any],\n        rationale: str,\n        auth_headers: dict[str, str] | None = None,\n        usage_tracking: bool = False,\n        payload_schema: dict[str, Any] | None = None,\n    ) -> dict[str, Any]:\n        \"\"\"Send the full payload to the action endpoint LLM for rewriting.\n\n        Posts a chat request to ``action_llm_url`` which is the fully\n        resolved gateway invocations URL.\n\n        When ``payload_schema`` is provided the sanitization request includes a\n        ``response_format`` constraint so the action LLM returns a JSON object\n        that matches the schema.  Pass ``None`` (the default) for passthrough or\n        request-side payloads where no schema constraint is needed.\n        \"\"\"\n        if not self.action_llm_url or not self.action_endpoint_name:\n            raise GuardrailViolation(\n                self.name,\n                \"Sanitization requires an action_llm_url but none was configured.\",\n            )\n\n        url = self.action_llm_url\n        path = f\"gateway/{self.action_endpoint_name}/mlflow/invocations\"\n        body: dict[str, Any] = {\n            \"messages\": [\n                {\n                    \"role\": \"user\",\n                    \"content\": _SANITIZE_SYSTEM_PROMPT.format(\n                        rationale=rationale,\n                        payload_json=json.dumps(payload, indent=2),\n                    ),\n                },\n            ],\n        }\n        if payload_schema is not None:","sourceCodeStart":210,"sourceCodeEnd":246,"githubUrl":"https://github.com/mlflow/mlflow/blob/6a27f2decc0b76eb1b54af31849784addb357dbc/mlflow/gateway/guardrails.py#L210-L246","documentation":"MLflow Gateway guardrail sanitization delegates the actual sanitization work to a secondary 'action LLM' endpoint. This GuardrailViolation is raised when the guardrail is configured to sanitize a payload but the guardrail instance has no action_llm_url (or action_endpoint_name) set, so there is nowhere to send the sanitization request.","triggerScenarios":"A guardrail with action=sanitize (VALIDATION passes without needing it) processes a payload via _enforce -> _sanitize while the guardrail config lacks action_llm_url/action_endpoint_name.","commonSituations":"Gateway route config defines a guardrail but omits the action-LLM endpoint settings; the guardrail is only validated for detection, not for sanitization; config was migrated or hand-edited and the action LLM block was dropped.","solutions":["Add action_llm_url and action_endpoint_name to the guardrail configuration pointing at a valid gateway LLM endpoint.","If sanitization is not needed, change the guardrail action to 'validation' (block) or 'info' instead of 'sanitize'.","Validate the guardrail config at load time before deploying the gateway."],"exampleFix":"// before\n\"guardrails\": [{\"name\": \"pii\", \"action\": \"sanitize\"}]\n// after\n\"guardrails\": [{\"name\": \"pii\", \"action\": \"sanitize\", \"action_llm_url\": \"http://localhost:5000/api/2.0/gateway\", \"action_endpoint_name\": \"sanitizer-llm\"}]","handlingStrategy":"validation","validationCode":"if not guardrail.action_llm_url or not guardrail.action_endpoint_name:\n    raise ValueError(f\"Guardrail {guardrail.name}: sanitization requires action_llm_url and action_endpoint_name\")","typeGuard":"def is_sanitization_ready(g) -> bool:\n    return bool(getattr(g, 'action_llm_url', None)) and bool(getattr(g, 'action_endpoint_name', None))","tryCatchPattern":"try:\n    payload = await guardrail.process_request(payload, ...)\nexcept GuardrailViolation as e:\n    logger.error(\"Guardrail %s misconfigured: %s\", e.guardrail_name, e)\n    raise","preventionTips":["Validate guardrail config (url + endpoint present when action is sanitize) at gateway startup.","Add a config schema check in CI for guardrail definitions.","Prefer 'validation' action when no action LLM is available."],"tags":["mlflow","gateway","guardrails","configuration"],"backgroundTag":"missing-config-value","analyzedSha":"6a27f2decc0b76eb1b54af31849784addb357dbc","analyzedAt":"2026-08-29T20:54:51.419Z","schemaVersion":2},"datasetVersion":"2026-08-29T22:17:34.462Z"}