{"record":{"id":"b543667327f4ef8d","repo":"BerriAI/litellm","slug":"microsoft-purview-guardrail-name-is-required","errorCode":null,"errorMessage":"Microsoft Purview: guardrail_name is required","messagePattern":"Microsoft Purview: guardrail_name is required","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/proxy/guardrails/guardrail_hooks/microsoft_purview/__init__.py","lineNumber":30,"sourceCode":"    import litellm\n\n    tenant_id: Final = getattr(litellm_params, \"tenant_id\", None)\n    client_id: Final = getattr(litellm_params, \"client_id\", None)\n\n    # client_secret can be passed via the standard api_key field or as\n    # a dedicated client_secret parameter.\n    client_secret: Final = litellm_params.api_key or getattr(litellm_params, \"client_secret\", None)\n\n    if not tenant_id:\n        raise ValueError(\"Microsoft Purview: tenant_id is required\")\n    if not client_id:\n        raise ValueError(\"Microsoft Purview: client_id is required\")\n    if not client_secret:\n        raise ValueError(\"Microsoft Purview: client_secret (or api_key) is required\")\n\n    guardrail_name: Final = guardrail.get(\"guardrail_name\")\n    if not guardrail_name:\n        raise ValueError(\"Microsoft Purview: guardrail_name is required\")\n\n    purview_guardrail: Final = MicrosoftPurviewDLPGuardrail(\n        guardrail_name=guardrail_name,\n        tenant_id=str(tenant_id),\n        client_id=str(client_id),\n        client_secret=str(client_secret),\n        purview_app_name=str(getattr(litellm_params, \"purview_app_name\", None) or \"LiteLLM\"),\n        user_id_field=str(getattr(litellm_params, \"user_id_field\", None) or \"user_id\"),\n        event_hook=litellm_params.mode,\n        default_on=litellm_params.default_on,\n    )\n\n    litellm.logging_callback_manager.add_litellm_callback(purview_guardrail)\n    return purview_guardrail\n\n\nguardrail_initializer_registry: Final = {\n    SupportedGuardrailIntegrations.MICROSOFT_PURVIEW.value: initialize_guardrail,","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/guardrails/guardrail_hooks/microsoft_purview/__init__.py#L12-L48","documentation":"Config-time ValueError raised by the microsoft_purview initializer when the guardrail dict itself has no 'guardrail_name' key. Unlike the credential fields, guardrail_name lives at the top level of the guardrails list entry (sibling of litellm_params), because LiteLLM uses it to register, look up, and reference the guardrail (e.g. via the 'guardrails' parameter on a model or request).","triggerScenarios":"A guardrails list entry containing only litellm_params; misspelling the key (guardrail-name, name); nesting guardrail_name inside litellm_params where the initializer's guardrail.get() cannot see it","commonSituations":"Hand-writing the first Purview guardrail entry from memory; YAML indentation drift pushing guardrail_name under litellm_params; refactoring that accidentally dropped the naming key","solutions":["Add 'guardrail_name' as a top-level key of the guardrail entry, next to litellm_params","Give it a stable unique name — it is what deployments reference via guardrails: [\"<name>\"]","Restart the proxy"],"exampleFix":"# before\nguardrails:\n  - litellm_params:\n      guardrail: microsoft_purview\n      tenant_id: \"...\"\n\n# after\nguardrails:\n  - guardrail_name: purview-dlp\n    litellm_params:\n      guardrail: microsoft_purview\n      tenant_id: \"...\"","handlingStrategy":"validation","validationCode":"def guardrail_entry_valid(g: dict) -> bool:\n    return (\n        isinstance(g, dict)\n        and isinstance(g.get(\"guardrail_name\"), str)\n        and bool(g[\"guardrail_name\"].strip())\n        and \"litellm_params\" in g\n    )\n\ninvalid = [g for g in cfg.get(\"guardrails\", []) if not guardrail_entry_valid(g)]","typeGuard":"from typing import TypedDict\n\nclass GuardrailEntry(TypedDict, total=False):\n    guardrail_name: str      # required, top level\n    litellm_params: dict\n\ndef is_guardrail_entry(x: object) -> bool:\n    return (\n        isinstance(x, dict)\n        and isinstance(x.get(\"guardrail_name\"), str)\n        and x[\"guardrail_name\"].strip() != \"\"\n    )","tryCatchPattern":null,"preventionTips":["Enforce guardrail config schema (guardrail_name + litellm_params) with a CI yaml-schema check","Name guardrails by function ('purview-dlp-prod') so missing names are caught in review"],"tags":["microsoft-purview","guardrails","configuration","litellm-proxy"],"backgroundTag":"missing-required-config","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}