BerriAI/litellm · error · CustomCodeCompilationError

Syntax error in custom code: {e}

Error message

Syntax error in custom code: {e}

What it means

CustomCodeCompilationError wrapping a Python SyntaxError raised while compiling the custom_code string inside the RestrictedPython sandbox (initial compile path). The message embeds the underlying syntax error with its line/column, so the submitted string itself is not valid Python for this compiler.

Source

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

        self._compiled_function = apply_fn

    def _compile_custom_code(self) -> None:
        """
        Compile the custom code and extract the apply_guardrail function.

        The code runs in a sandboxed environment with only the allowed primitives.
        """
        with self._compile_lock:
            if self._compiled_function is not None:
                return

            try:
                self._do_compile()
                verbose_proxy_logger.debug("Custom code guardrail '%s' compiled successfully", self.guardrail_name)

            except SyntaxError as e:
                self._compile_error = f"Syntax error in custom code: {e}"
                raise CustomCodeCompilationError(self._compile_error) from e
            except CustomCodeCompilationError:
                raise
            except Exception as e:
                self._compile_error = f"Failed to compile custom code: {e}"
                raise CustomCodeCompilationError(self._compile_error) from e

    @log_guardrail_information
    async def apply_guardrail(
        self,
        inputs: GenericGuardrailAPIInputs,
        request_data: dict,
        input_type: Literal["request", "response"],
        logging_obj: Optional["LiteLLMLoggingObj"] = None,
    ) -> GenericGuardrailAPIInputs:
        """
        Apply the custom code guardrail to the inputs.

        This method calls the user-defined apply_guardrail function and

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Reproduce locally with compile(code, '<custom>', 'exec') to get the exact failing line, then fix it
  2. Fix the YAML block-scalar indentation so the string reaches the proxy unchanged
  3. Keep the code to plain functions and avoid exotic syntax the sandbox policy restricts
  4. After fixing, hot-update via the guardrail update API or restart the proxy

Example fix

# before (value of custom_code): missing colon and bad indent
def apply_guardrail(inputs, request_data, input_type)
      return allow()

# after
def apply_guardrail(inputs, request_data, input_type):
    return allow()
Defensive patterns

Strategy: validation

Validate before calling

def check_syntax(src: str) -> None:
    try:
        compile(src, '<custom_code>', 'exec')
    except SyntaxError as e:
        raise ValueError(f'custom_code has a syntax error at line {e.lineno}: {e.msg}') from e

Try / catch

from litellm.proxy.guardrails.guardrail_hooks.custom_code.custom_code_guardrail import CustomCodeCompilationError
try:
    guardrail._compile_custom_code()
except CustomCodeCompilationError as e:
    if 'Syntax error' in str(e):
        ...  # fix the named line in custom_code; safe to keep old code serving
    raise

Prevention

When it happens

Trigger: custom_code contains invalid Python: bad indentation, unclosed quotes/brackets, or constructs the RestrictedPython policy rewrites into rejected code; also YAML block-scalar mistakes that mangle the string before it reaches the compiler.

Common situations: Block scalar (custom_code: |) indentation lost or extra-indented when copied; tabs mixed with spaces; smart quotes pasted from rich-text docs; f-string nesting unsupported by the runtime.

Related errors


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