{"record":{"id":"87065ab09113652d","repo":"BerriAI/litellm","slug":"custom-code-guardrail-not-compiled-self-compile","errorCode":null,"errorMessage":"Custom code guardrail not compiled: {self._compile_error}","messagePattern":"Custom code guardrail not compiled: (.+?)","errorType":"exception","errorClass":"CustomCodeExecutionError","httpStatus":null,"severity":"error","filePath":"litellm/proxy/guardrails/guardrail_hooks/custom_code/custom_code_guardrail.py","lineNumber":226,"sourceCode":"        Async functions are recommended when using http_request, http_get, or\n        http_post primitives to avoid blocking the event loop.\n\n        Args:\n            inputs: Dictionary containing texts, images, tool_calls\n            request_data: The original request data with metadata\n            input_type: \"request\" for pre-call, \"response\" for post-call\n            logging_obj: Optional logging object\n\n        Returns:\n            GenericGuardrailAPIInputs - possibly modified\n\n        Raises:\n            HTTPException: If content is blocked\n            CustomCodeExecutionError: If execution fails\n        \"\"\"\n        if self._compiled_function is None:\n            if self._compile_error:\n                raise CustomCodeExecutionError(f\"Custom code guardrail not compiled: {self._compile_error}\")\n            raise CustomCodeExecutionError(\"Custom code guardrail not compiled\")\n\n        try:\n            # Prepare inputs dict for the function\n\n            # Prepare request_data with safe subset of information\n            safe_request_data: Final = self._prepare_safe_request_data(request_data)\n\n            # Execute the custom function - handle both sync and async functions\n            result = self._compiled_function(inputs, safe_request_data, input_type)\n\n            # If the function is async (returns a coroutine), await it\n            if asyncio.iscoroutine(result):\n                result = await result\n\n            # Process the result\n            return self._process_result(\n                result=result,","sourceCodeStart":208,"sourceCodeEnd":244,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/guardrails/guardrail_hooks/custom_code/custom_code_guardrail.py#L208-L244","documentation":"CustomCodeExecutionError raised at request time when a hooked call reaches a custom-code guardrail whose compilation previously failed: the stored _compile_error is embedded in the message so the operator can see the original cause. Compilation is lazy and a failed compile does not unregister the guardrail, so every subsequent request on that hook keeps raising this until the code is fixed or the guardrail removed.","triggerScenarios":"custom_code contained a compile error that first surfaced on an earlier guarded request (config loaded fine because compile is deferred); all later requests hitting the same hook receive 'Custom code guardrail not compiled: <original error>'.","commonSituations":"A bad code deploy passes config load, then production traffic fails 100% with the same nested compile reason; logs show the identical wrapped SyntaxError on every call; hot-reload of config reintroduced a previously broken snippet.","solutions":["Fix the compile error named in the embedded message, then update the code via the guardrail update API or reload the config","If the fix is not immediate, disable or remove the guardrail so traffic stops failing on that hook","Pre-compile custom guardrails at startup/CI (eager compile) so a broken snippet fails the deploy, not live requests"],"exampleFix":"# the message embeds the ORIGINAL compile failure, e.g.:\n# 'Custom code guardrail not compiled: Syntax error in custom code: invalid syntax (custom, line 3)'\n# before: leaving the broken guardrail attached -> every request fails\n# after: fix line 3 of custom_code, then hot-update the guardrail (old code keeps serving until a clean update lands)\n#   guardrails:\n#     - guardrail_name: my-custom-guardrail\n#       litellm_params:\n#         custom_code: |\n#           def apply_guardrail(inputs, request_data, input_type):  # <- colon added\n#               return allow()","handlingStrategy":"try-catch","validationCode":"from litellm.proxy.guardrails.guardrail_hooks.custom_code.custom_code_guardrail import CustomCodeGuardrail\n\n# eager-compile at registration so a broken snippet fails startup, not live traffic\nguardrail = CustomCodeGuardrail(guardrail_name='g', custom_code=src, event_hook='pre_call', default_on=True)\nguardrail._compile_custom_code()","typeGuard":null,"tryCatchPattern":"from litellm.proxy.guardrails.guardrail_hooks.custom_code.custom_code_guardrail import CustomCodeExecutionError\ntry:\n    inputs = await guardrail.apply_guardrail(inputs, request_data, 'request')\nexcept CustomCodeExecutionError as e:\n    if 'not compiled' in str(e):\n        # guardrail is dead code - disable it and alert; do not let every request 500\n        log.error('custom guardrail not compiled, bypassing', detail=str(e))\n        raise HTTPException(status_code=503, detail='guardrail misconfigured') from e\n    raise","preventionTips":["Eagerly compile custom-code guardrails at startup/registration so failures are deploy-time, not request-time","Alert on the 'not compiled' message pattern - it means 100% of hooked traffic is failing","Track the original compile error to closure: fix code, hot-update, verify with a canary request"],"tags":["guardrails","custom-code","lazy-compilation","runtime-error","litellm-proxy"],"backgroundTag":"guardrail-not-compiled","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}