BerriAI/litellm · error · ValueError

Microsoft Purview: client_id is required

Error message

Microsoft Purview: client_id is required

What it means

Config-time ValueError from the microsoft_purview guardrail initializer. After tenant_id passes, the next required Entra ID credential is client_id — the Application (client) ID of the Azure app registration the guardrail authenticates as. LiteLLM throws this when litellm_params.client_id is absent or empty.

Source

Thrown at litellm/proxy/guardrails/guardrail_hooks/microsoft_purview/__init__.py:24

if TYPE_CHECKING:
    from litellm.types.guardrails import Guardrail, LitellmParams


def initialize_guardrail(litellm_params: "LitellmParams", guardrail: "Guardrail"):
    import litellm

    tenant_id: Final = getattr(litellm_params, "tenant_id", None)
    client_id: Final = getattr(litellm_params, "client_id", None)

    # client_secret can be passed via the standard api_key field or as
    # a dedicated client_secret parameter.
    client_secret: Final = litellm_params.api_key or getattr(litellm_params, "client_secret", None)

    if not tenant_id:
        raise ValueError("Microsoft Purview: tenant_id is required")
    if not client_id:
        raise ValueError("Microsoft Purview: client_id is required")
    if not client_secret:
        raise ValueError("Microsoft Purview: client_secret (or api_key) is required")

    guardrail_name: Final = guardrail.get("guardrail_name")
    if not guardrail_name:
        raise ValueError("Microsoft Purview: guardrail_name is required")

    purview_guardrail: Final = MicrosoftPurviewDLPGuardrail(
        guardrail_name=guardrail_name,
        tenant_id=str(tenant_id),
        client_id=str(client_id),
        client_secret=str(client_secret),
        purview_app_name=str(getattr(litellm_params, "purview_app_name", None) or "LiteLLM"),
        user_id_field=str(getattr(litellm_params, "user_id_field", None) or "user_id"),
        event_hook=litellm_params.mode,
        default_on=litellm_params.default_on,
    )

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Set 'client_id' inside the same litellm_params block — use the Application (client) ID, not the Object ID, from the app registration
  2. Verify the app registration exists in the same tenant as tenant_id
  3. Restart the proxy to re-run guardrail initialization

Example fix

# before
litellm_params:
  guardrail: microsoft_purview
  tenant_id: "11111111-..."

# after
litellm_params:
  guardrail: microsoft_purview
  tenant_id: "11111111-..."
  client_id: "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
Defensive patterns

Strategy: validation

Validate before calling

PURVIEW_REQUIRED = ("tenant_id", "client_id", "client_secret")

def purview_config_ok(lp: dict) -> tuple[bool, list[str]]:
    missing = [k for k in PURVIEW_REQUIRED if not lp.get(k) and not (k == "client_secret" and lp.get("api_key"))]
    return (not missing, missing)

ok, missing = purview_config_ok(guardrail_entry["litellm_params"])
assert ok, f"fix before deploy: {missing}"

Try / catch

try:
    guard = build_purview_guardrail(entry)
except ValueError as e:
    # all Purview config errors share the 'Microsoft Purview:' prefix
    if str(e).startswith("Microsoft Purview:"):
        report_config_error(entry, str(e))
    raise

Prevention

When it happens

Trigger: Purview guardrail config that includes tenant_id but omits client_id; supplying the Object ID of the app registration instead of the Application (client) ID; empty string from a templating/Ansible variable that did not render.

Common situations: Copy-pasting from Azure portal and grabbing the wrong GUID (object ID vs application ID); splitting credentials across a secrets manager where the client_id entry was never added; partially filled example config after fixing the previous tenant_id error.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/6546b4bc1ab143a3. Report an issue: GitHub.