{"record":{"id":"5cd657bfba1e5693","repo":"BerriAI/litellm","slug":"apply-guardrail-must-be-a-callable-function","errorCode":null,"errorMessage":"'apply_guardrail' must be a callable function","messagePattern":"'apply_guardrail' must be a callable function","errorType":"exception","errorClass":"CustomCodeCompilationError","httpStatus":null,"severity":"error","filePath":"litellm/proxy/guardrails/guardrail_hooks/custom_code/custom_code_guardrail.py","lineNumber":163,"sourceCode":"            GuardrailEventHooks.during_mcp_call,\n            GuardrailEventHooks.logging_only,\n        ]\n\n    def _do_compile(self) -> None:\n        \"\"\"Internal compilation method without lock. Expected to run inside _compile_lock.\"\"\"\n        exec_globals: Final = build_sandbox_globals()\n        compiled: Final = compile_sandboxed(self.custom_code)\n        exec(compiled, exec_globals)  # noqa: S102\n\n        if \"apply_guardrail\" not in exec_globals:\n            raise CustomCodeCompilationError(\n                \"Custom code must define an 'apply_guardrail' function. \"\n                \"Expected signature: apply_guardrail(inputs, request_data, input_type)\"\n            )\n\n        apply_fn: Final = exec_globals[\"apply_guardrail\"]\n        if not callable(apply_fn):\n            raise CustomCodeCompilationError(\"'apply_guardrail' must be a callable function\")\n\n        self._compiled_function = apply_fn\n\n    def _compile_custom_code(self) -> None:\n        \"\"\"\n        Compile the custom code and extract the apply_guardrail function.\n\n        The code runs in a sandboxed environment with only the allowed primitives.\n        \"\"\"\n        with self._compile_lock:\n            if self._compiled_function is not None:\n                return\n\n            try:\n                self._do_compile()\n                verbose_proxy_logger.debug(\"Custom code guardrail '%s' compiled successfully\", self.guardrail_name)\n\n            except SyntaxError as e:","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/guardrails/guardrail_hooks/custom_code/custom_code_guardrail.py#L145-L181","documentation":"CustomCodeCompilationError raised when the sandboxed code defines a top-level apply_guardrail name but it is not callable (e.g. assigned an int, string, or None). The compile pipeline found the symbol yet cannot use it as the guardrail entry function.","triggerScenarios":"custom_code contains apply_guardrail = None, apply_guardrail = 'see docs', or a variable that shadows a previously defined function of that name; compilation succeeds up to the callable() check and then aborts.","commonSituations":"Reusing the name for a flag/config constant; a templating step assigns a string value over the function; accidental paste of documentation text at module level.","solutions":["Make apply_guardrail a plain def (or other callable) at top level","Remove any variable, constant, or doc string that rebinds the name","Re-run the sandbox preflight (compile + exec + callable check) before redeploying"],"exampleFix":"# before: name shadowed by a constant\napply_guardrail = 'block if flagged'\n\n# after\ndef apply_guardrail(inputs, request_data, input_type):\n    return allow()","handlingStrategy":"validation","validationCode":"from litellm.proxy.guardrails.guardrail_hooks.custom_code.sandbox import (\n    build_sandbox_globals, compile_sandboxed,\n)\n\ndef preflight(custom_code: str) -> None:\n    g = build_sandbox_globals()\n    exec(compile_sandboxed(custom_code), g)\n    fn = g.get('apply_guardrail')\n    assert fn is not None, 'apply_guardrail not defined'\n    assert callable(fn), 'apply_guardrail must be a function, not a value'","typeGuard":"def is_valid_entrypoint(exec_globals: dict) -> bool:\n    fn = exec_globals.get('apply_guardrail')\n    return fn is not None and callable(fn)","tryCatchPattern":null,"preventionTips":["Lint custom_code for rebindings of the apply_guardrail name (treat it as reserved)","Keep module top level to the single function definition; put flags/constants under different names"],"tags":["guardrails","custom-code","sandbox","entrypoint","type-error"],"backgroundTag":"sandbox-entrypoint-not-callable","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}