BerriAI/litellm · error · ValueError

Invalid identifier : path traversal detected

Error message

Invalid identifier {identifier!r}: path traversal detected

What it means

Companion guard to the disallowed-character check: `_sanitize_id` additionally rejects any identifier containing '..' even if it passed the character check, because '..' in a URL path segment enables path-traversal ('../' style) attacks against the Phoenix API base URL. This is a deliberate security check, not a formatting nit.

Solutions

  1. Pass only opaque identifiers issued by Phoenix; never build IDs from path-like segments
  2. Sanitize external input before it reaches litellm: reject or encode any identifier containing '..'
  3. Log the rejected identifier at your boundary so misuse is visible in your own telemetry

Example fix

# before
prompt_version_id = "../v1/prompt_versions/abc"  # '..' -> path traversal ValueError

# after
prompt_version_id = "abc"  # opaque ID from Phoenix
Defensive patterns

Strategy: validation

Validate before calling

def reject_traversal(identifier: str) -> str:
    if ".." in identifier:
        raise ValueError("path traversal sequence rejected")
    return identifier

prompt_id = reject_traversal(raw_input)

Type guard

def is_traversal_free(identifier: str) -> bool:
    return isinstance(identifier, str) and ".." not in identifier

Try / catch

try:
    client.get_prompt_version(prompt_version_id)
except ValueError as e:
    if "path traversal" in str(e):
        log.security("blocked traversal attempt: %r", prompt_version_id)  # audit, do not retry
    raise

Prevention

When it happens

Trigger: Passing a prompt or prompt-version identifier containing '..' anywhere, e.g. prompt_version_id='../admin/prompt_versions', or an ID like 'my..prompt'. Raised synchronously in ArizePhoenixClient before any HTTP call.

Common situations: Unsanitized user input flowing into prompt_id from a web endpoint; test fixtures with placeholder IDs like '../id'; constructed IDs that concatenate directory-like segments.

Understand the failure class

Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.

Related errors


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

Appendix: source

Thrown at litellm/integrations/arize/arize_phoenix_client.py:16

"""
Arize Phoenix API client for fetching prompt versions from Arize Phoenix.
"""

import urllib.parse
from typing import Any, Final

from litellm.llms.custom_httpx.http_handler import HTTPHandler


def _sanitize_id(identifier: str) -> str:
    """Reject path traversal characters and URL-encode the identifier."""
    if any(c in identifier for c in ("/", "\\", "#", "?")):
        raise ValueError(f"Invalid identifier {identifier!r}: contains disallowed characters")
    if ".." in identifier:
        raise ValueError(f"Invalid identifier {identifier!r}: path traversal detected")
    return urllib.parse.quote(identifier, safe="")


class ArizePhoenixClient:
    """
    Client for interacting with Arize Phoenix API to fetch prompt versions.

    Supports:
    - Authentication with Bearer tokens
    - Fetching prompt versions
    - Direct API base URL configuration
    """

    def __init__(self, api_key: str | None = None, api_base: str | None = None):
        """
        Initialize the Arize Phoenix client.

        Args:

View on GitHub (pinned to 77b7c6c40c)