{"record":{"id":"0eb9d08a02eb8bc1","repo":"BerriAI/litellm","slug":"for-sap-masking-module-config-you-must-set-exactly","errorCode":null,"errorMessage":"For SAP Masking Module Config you must set exactly one of: 'providers' or 'masking_providers', not both.","messagePattern":"For SAP Masking Module Config you must set exactly one of: 'providers' or 'masking_providers', not both\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"litellm/llms/sap/chat/models.py","lineNumber":381,"sourceCode":"    Args:\n        providers: list of masking service provider configurations\n        masking_providers: list of masking provider configurations\n    IMPORTANT: use exactly one of the parameters to set the list of masking provider configurations.\n    DEPRECATED: parameter 'masking_providers' will be removed Sept 15, 2026. Use 'providers' instead.\n    \"\"\"\n\n    providers: list[MaskingProviderConfig] | None = Field(min_length=1, default=None)\n    masking_providers: list[MaskingProviderConfig] | None = Field(min_length=1, default=None)\n\n    @model_validator(mode=\"after\")\n    def enforce_exactly_one_provider_list(self):\n        has_providers: Final = self.providers is not None\n        has_masking_providers: Final = self.masking_providers is not None\n\n        if not has_providers and not has_masking_providers:\n            raise ValueError(\"For SAP Masking Module Config you must provide 'providers'.\")\n        if has_providers and has_masking_providers:\n            raise ValueError(\n                \"For SAP Masking Module Config you must set exactly one of: 'providers' or 'masking_providers', not both.\"\n            )\n\n        if has_masking_providers:\n            warnings.warn(\n                \"The 'masking_providers' parameter is deprecated and will be removed on Sept 15, 2026. \"\n                \"Use 'providers' instead.\",\n                DeprecationWarning,\n                stacklevel=5,\n            )\n\n        return self\n\n\nclass AzureThreshold(int, Enum):\n    \"\"\"\n    Enumerates the threshold levels for the Azure Content Safety service.\n","sourceCodeStart":363,"sourceCodeEnd":399,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/llms/sap/chat/models.py#L363-L399","documentation":"MaskingModuleConfig rejects requests that set both 'providers' and the deprecated 'masking_providers' - the validator requires exactly one so it is unambiguous which list applies. Setting both raises this ValueError before any network call.","triggerScenarios":"A request body containing both providers and masking_providers keys under the masking module - typically legacy config partially migrated to the new field name.","commonSituations":"Migrating from masking_providers to providers and leaving the old key in place; merging a deprecated base config with a new overlay so both keys survive; copying SAP docs examples that show old and new side by side.","solutions":["Delete the deprecated 'masking_providers' key and keep only 'providers'.","Audit config-merge code so renamed fields replace rather than accumulate.","Note the deprecation: masking_providers is removed Sept 15, 2026, so migrate now."],"exampleFix":"# before\n{'masking': {'providers': [a], 'masking_providers': [b]}}\n# after\n{'masking': {'providers': [a]}}","handlingStrategy":"validation","validationCode":"def sanitize_masking(masking: dict) -> dict:\n    masking = dict(masking)\n    masking.pop('masking_providers', None)  # deprecated; never send both\n    if 'providers' not in masking:\n        masking['providers'] = masking.get('providers')  # missing case validated upstream\n    return masking","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Grep configs for the deprecated masking_providers key and migrate.","Make config merge code replace renamed keys instead of keeping both."],"tags":["sap","masking","validation","mutually-exclusive"],"backgroundTag":"mutually-exclusive-parameters","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}