BerriAI/litellm · error · ValueError

Category file path '{path}' is outside the allowed categorie

Error message

Category file path '{path}' is outside the allowed categories directory

What it means

ValueError from ContentFilterGuardrail._assert_within_categories_dir raised when os.path.commonpath() itself throws — which happens on Windows when the resolved category file path and the guardrail module directory live on different drives (e.g. D:\policies\cat.yaml vs C:\...\site-packages\litellm). Containment cannot even be computed across drives, so the jail rejects the path. Note the message omits the directory because commonpath failed before the comparison.

Source

Thrown at litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/content_filter.py:353

    @staticmethod
    def _category_config_view(cat_config: ContentFilterCategoryConfig) -> _CategoryConfigView:
        return {
            "category": cat_config.get("category"),
            "enabled": cat_config.get("enabled", True),
            "action": cat_config.get("action"),
            "category_file": cat_config.get("category_file"),
        }

    @staticmethod
    def _assert_within_categories_dir(path: str, categories_dir: str) -> None:
        """Raise ValueError if path escapes the categories directory."""
        resolved: Final = os.path.realpath(path)
        allowed: Final = os.path.realpath(categories_dir)
        try:
            common: Final = os.path.commonpath([resolved, allowed])
        except ValueError:
            # commonpath() raises ValueError on Windows when paths span different drives
            raise ValueError(f"Category file path '{path}' is outside the allowed categories directory")
        if common != allowed:
            raise ValueError(
                f"Category file path '{path}' is outside the allowed categories directory '{categories_dir}'"
            )

    def _resolve_category_file_path(self, file_path: str) -> str:
        """
        Resolve a category file path that may be relative.

        Paths in policy templates (e.g. category_file) are often stored as
        relative paths like "litellm/proxy/.../policy_templates/file.yaml".
        These only work when the CWD is the project root. In production
        (Docker, installed packages, etc.) the CWD is different, so the
        file isn't found.

        Resolution order:
        1. Return as-is if absolute or already exists (jailed to module dir).
        2. Try joining the full path relative to this module's directory (jailed).

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Move the category YAML files onto the same drive as the litellm installation, under the litellm_content_filter module directory.
  2. Use a relative category_file path that resolves inside the module directory (the resolver jails those safely).
  3. If the files must stay outside the package on a trusted host, set LITELLM_CONTENT_FILTER_ALLOW_EXTERNAL_PATHS=true to disable the directory jail.
  4. Prefer running the proxy in the official Docker image (Linux) where cross-drive paths cannot occur.

Example fix

# before (Windows, cross-drive)
policy_template:
  category_file: 'D:\policies\pii.yaml'

# after — file relocated inside the module dir, relative path
category_file: 'policy_templates/pii.yaml'
Defensive patterns

Strategy: validation

Validate before calling

# Startup check: a category path must be comparable with the module dir (same drive on Windows)
import os

def category_path_comparable(path: str, module_dir: str) -> bool:
    try:
        os.path.commonpath([os.path.realpath(path), os.path.realpath(module_dir)])
        return True
    except ValueError:
        return False  # cross-drive (Windows) — will be rejected by the jail

# if not category_path_comparable(cfg_path, os.path.dirname(litellm_content_filter.__file__)): fix or relocate

Prevention

When it happens

Trigger: Running the proxy on Windows (or a Windows CI runner) with a category_file value that resolves to an absolute path on a different drive than the litellm package directory, while LITELLM_CONTENT_FILTER_ALLOW_EXTERNAL_PATHS is not set.

Common situations: Windows deployments or tests that pass absolute category paths from another drive; drive-relative or cross-drive configs copied from Linux examples that used /-style paths.

Related errors


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