BerriAI/litellm · error · CustomCodeExecutionError

Custom code guardrail not compiled: {self._compile_error}

Error message

Custom code guardrail not compiled: {self._compile_error}

What it means

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.

Source

Thrown at litellm/proxy/guardrails/guardrail_hooks/custom_code/custom_code_guardrail.py:226

        Async functions are recommended when using http_request, http_get, or
        http_post primitives to avoid blocking the event loop.

        Args:
            inputs: Dictionary containing texts, images, tool_calls
            request_data: The original request data with metadata
            input_type: "request" for pre-call, "response" for post-call
            logging_obj: Optional logging object

        Returns:
            GenericGuardrailAPIInputs - possibly modified

        Raises:
            HTTPException: If content is blocked
            CustomCodeExecutionError: If execution fails
        """
        if self._compiled_function is None:
            if self._compile_error:
                raise CustomCodeExecutionError(f"Custom code guardrail not compiled: {self._compile_error}")
            raise CustomCodeExecutionError("Custom code guardrail not compiled")

        try:
            # Prepare inputs dict for the function

            # Prepare request_data with safe subset of information
            safe_request_data: Final = self._prepare_safe_request_data(request_data)

            # Execute the custom function - handle both sync and async functions
            result = self._compiled_function(inputs, safe_request_data, input_type)

            # If the function is async (returns a coroutine), await it
            if asyncio.iscoroutine(result):
                result = await result

            # Process the result
            return self._process_result(
                result=result,

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Fix the compile error named in the embedded message, then update the code via the guardrail update API or reload the config
  2. If the fix is not immediate, disable or remove the guardrail so traffic stops failing on that hook
  3. Pre-compile custom guardrails at startup/CI (eager compile) so a broken snippet fails the deploy, not live requests

Example fix

# the message embeds the ORIGINAL compile failure, e.g.:
# 'Custom code guardrail not compiled: Syntax error in custom code: invalid syntax (custom, line 3)'
# before: leaving the broken guardrail attached -> every request fails
# after: fix line 3 of custom_code, then hot-update the guardrail (old code keeps serving until a clean update lands)
#   guardrails:
#     - guardrail_name: my-custom-guardrail
#       litellm_params:
#         custom_code: |
#           def apply_guardrail(inputs, request_data, input_type):  # <- colon added
#               return allow()
Defensive patterns

Strategy: try-catch

Validate before calling

from litellm.proxy.guardrails.guardrail_hooks.custom_code.custom_code_guardrail import CustomCodeGuardrail

# eager-compile at registration so a broken snippet fails startup, not live traffic
guardrail = CustomCodeGuardrail(guardrail_name='g', custom_code=src, event_hook='pre_call', default_on=True)
guardrail._compile_custom_code()

Try / catch

from litellm.proxy.guardrails.guardrail_hooks.custom_code.custom_code_guardrail import CustomCodeExecutionError
try:
    inputs = await guardrail.apply_guardrail(inputs, request_data, 'request')
except CustomCodeExecutionError as e:
    if 'not compiled' in str(e):
        # guardrail is dead code - disable it and alert; do not let every request 500
        log.error('custom guardrail not compiled, bypassing', detail=str(e))
        raise HTTPException(status_code=503, detail='guardrail misconfigured') from e
    raise

Prevention

When it happens

Trigger: 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>'.

Common situations: 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.

Related errors


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