{"record":{"id":"1f31e7ef8c40634c","repo":"BerriAI/litellm","slug":"custom-code-guardrail-not-compiled","errorCode":null,"errorMessage":"Custom code guardrail not compiled","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":227,"sourceCode":"        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,\n                inputs=inputs,","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/guardrails/guardrail_hooks/custom_code/custom_code_guardrail.py#L209-L245","documentation":"CustomCodeExecutionError raised when the custom-code guardrail executes with no compiled function and no recorded compile error — the instance's _compiled_function is None while _compile_error is also None. With the normal flow a compile is attempted before this state can be observed, so hitting this branch usually indicates an internal/lazy-compile race or state loss (e.g. a rollback in the update flow when no previously compiled function existed), and is worth a bug report rather than a config fix.","triggerScenarios":"A hooked request fires on a guardrail instance whose compile never ran to completion — e.g. traffic racing the very first compile, or update_custom_code rolling back when there was no old compiled function to restore.","commonSituations":"Rare; observed under concurrent first-request plus code update, or when a guardrail object is constructed programmatically outside the standard registration path.","solutions":["Reload/re-register the guardrail (config reload or proxy restart) so a clean compile runs","Retry the request once after the reload — a transient race at first compile resolves itself","If reproducible, capture proxy logs plus the guardrail config (with secrets removed) and open a litellm issue"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"from litellm.proxy.guardrails.guardrail_hooks.custom_code.custom_code_guardrail import CustomCodeGuardrail\n\n# compile once at registration; guards against the no-function/no-error internal state\nguardrail = CustomCodeGuardrail(guardrail_name='g', custom_code=src, event_hook='pre_call', default_on=True)\nguardrail._compile_custom_code()\nassert guardrail._compiled_function is not None","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 str(e) == 'Custom code guardrail not compiled':  # no stored reason: internal state issue\n        log.error('guardrail in uninitialized state; re-registering')\n        guardrail._compile_custom_code()  # one repair attempt, then re-raise if it persists\n        inputs = await guardrail.apply_guardrail(inputs, request_data, 'request')\n    else:\n        raise","preventionTips":["Compile custom-code guardrails eagerly at registration instead of relying on the lazy first-request path","Avoid mutating guardrail code concurrently with live traffic; serialize config updates and reloads","If it recurs, capture logs and file a litellm issue - this branch indicates an internal state gap"],"tags":["guardrails","custom-code","internal-state","race-condition","litellm-proxy"],"backgroundTag":"guardrail-not-compiled","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}