{"record":{"id":"e5ad3431e3965b6f","repo":"BerriAI/litellm","slug":"custom-code-guardrail-requires-custom-code-in-li","errorCode":null,"errorMessage":"Custom code guardrail requires 'custom_code' in litellm_params","messagePattern":"Custom code guardrail requires 'custom_code' in litellm_params","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/proxy/guardrails/guardrail_hooks/custom_code/__init__.py","lineNumber":44,"sourceCode":"    Initialize a custom code guardrail.\n\n    Args:\n        litellm_params: Configuration parameters including the custom code\n        guardrail: The guardrail configuration dict\n\n    Returns:\n        CustomCodeGuardrail instance\n    \"\"\"\n    import litellm\n\n    guardrail_name: Final = guardrail.get(\"guardrail_name\")\n    if not guardrail_name:\n        raise ValueError(\"Custom code guardrail requires a guardrail_name\")\n\n    # Get the custom code from litellm_params\n    custom_code: Final = getattr(litellm_params, \"custom_code\", None)\n    if not custom_code:\n        raise ValueError(\"Custom code guardrail requires 'custom_code' in litellm_params\")\n\n    custom_code_guardrail: Final = CustomCodeGuardrail(\n        guardrail_name=guardrail_name,\n        custom_code=custom_code,\n        event_hook=litellm_params.mode,\n        default_on=litellm_params.default_on,\n    )\n\n    litellm.logging_callback_manager.add_litellm_callback(custom_code_guardrail)\n    return custom_code_guardrail\n\n\nguardrail_initializer_registry: Final = {\n    SupportedGuardrailIntegrations.CUSTOM_CODE.value: initialize_guardrail,\n}\n\nguardrail_class_registry: Final = {\n    SupportedGuardrailIntegrations.CUSTOM_CODE.value: CustomCodeGuardrail,","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/guardrails/guardrail_hooks/custom_code/__init__.py#L26-L62","documentation":"ValueError raised by the custom-code guardrail factory when the guardrails entry routes to the custom-code guardrail (guardrail_name is present) but litellm_params has no custom_code attribute or it is empty. The guardrail is entirely defined by that code string, so its absence is a config schema violation caught at instantiation.","triggerScenarios":"A guardrails entry with guardrail_name and a custom-code mode in litellm_params but no custom_code key; or custom_code set to an empty string/None (e.g. templated config rendered the value empty).","commonSituations":"Mode set from an example but the code block not filled in; YAML block scalar (custom_code: |) with wrong indentation so the value parses as empty; CI templating stripping the field.","solutions":["Add custom_code under litellm_params with a block scalar containing def apply_guardrail(...)","Check the block-scalar indentation (code lines must be indented consistently under custom_code: |)","Render and inspect the final YAML (e.g. yaml.safe_load) in CI to confirm the key is a non-empty string"],"exampleFix":"# before\nguardrails:\n  - guardrail_name: my-custom-guardrail\n    litellm_params:\n      mode: guardrail_runs_before_llm_call\n\n# after\nguardrails:\n  - guardrail_name: my-custom-guardrail\n    litellm_params:\n      mode: guardrail_runs_before_llm_call\n      custom_code: |\n        def apply_guardrail(inputs, request_data, input_type):\n            for text in inputs.get('texts') or []:\n                if 'forbidden' in text:\n                    return block('forbidden term')\n            return allow()","handlingStrategy":"validation","validationCode":"import yaml\n\ncfg = yaml.safe_load(open('config.yaml'))\nfor g in cfg.get('guardrails') or []:\n    lp = g.get('litellm_params') or {}\n    if not isinstance(lp.get('custom_code'), str) or not lp['custom_code'].strip():\n        raise ValueError(f\"guardrail {g.get('guardrail_name')}: litellm_params.custom_code must be a non-empty string\")","typeGuard":null,"tryCatchPattern":"try:\n    guardrail = instantiate_custom_code_guardrail(litellm_params=lp, guardrail=entry)\nexcept ValueError as e:\n    # config rejected before any traffic is served\n    raise SystemExit(f'invalid guardrail config: {e}') from e","preventionTips":["Render the final YAML in CI and assert custom_code is a non-empty string (catches block-scalar indentation bugs)","Keep a golden working guardrails entry as a template so new entries start from a valid shape"],"tags":["guardrails","custom-code","config","yaml","validation","litellm-proxy"],"backgroundTag":"guardrail-misconfigured","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}