BerriAI/litellm · error · ValueError
Path parameter '{param_name}' must not contain path separato
Error message
Path parameter '{param_name}' must not contain path separators What it means
Security guard in litellm's OpenAPI-to-MCP tool generator. When a generated MCP tool substitutes a caller-supplied value into a URL path segment, _sanitize_path_parameter_value rejects any value containing / (backslashes are normalized to / first) with this ValueError, blocking path traversal and URL-segment injection. On the generated tool's REST execution path the ValueError is caught and returned as the tool result string "Invalid path parameter: ...", so it usually surfaces as a failed tool result rather than an exception.
Source
Thrown at litellm/proxy/_experimental/mcp_server/openapi_to_mcp_generator.py:121
# Set from MCPServerManager.resolve_openapi_upstream_auth; authoritative
# over every other Authorization source in _merge_openapi_tool_request_headers.
_request_resolved_auth_headers: Final[contextvars.ContextVar[dict[str, str] | None]] = contextvars.ContextVar(
"_request_resolved_auth_headers", default=None
)
def _sanitize_path_parameter_value(param_value: object, param_name: str) -> str:
"""Ensure path params cannot introduce directory traversal."""
if param_value is None:
return ""
value_str: Final = str(param_value)
if value_str == "":
return ""
normalized_value: Final = value_str.replace("\\", "/")
if "/" in normalized_value:
raise ValueError(f"Path parameter '{param_name}' must not contain path separators")
if any(part in {".", ".."} for part in PurePosixPath(normalized_value).parts):
raise ValueError(f"Path parameter '{param_name}' cannot include '.' or '..' segments")
return quote(value_str, safe="")
def load_openapi_spec(filepath: str) -> dict[str, Any]:
"""
Sync wrapper. For URL specs, use the shared/custom MCP httpx client.
"""
try:
# If we're already inside an event loop, prefer the async function.
asyncio.get_running_loop()
raise RuntimeError(
"load_openapi_spec() was called from within a running event loop. "
"Use 'await load_openapi_spec_async(...)' instead."
)View on GitHub (pinned to 77b7c6c40c)
Solutions
- Pass exactly one URL path segment per parameter - strip or restructure slashes before calling the tool.
- If the argument came from user input or another file path, split it and use the real segment (or a tool whose OpenAPI path has one parameter per segment).
- If the upstream API genuinely accepts an encoded slash inside one segment, verify against the generated tool's input schema; the generator percent-encodes the whole value (quote safe=""), so pre-encoding a slash yourself results in double-encoding - use a slash-free identifier instead.
Example fix
# before
result = await call_mcp_tool(server_id="myapi", tool_name="get_file", arguments={"file_id": "docs/readme.md"})
# -> tool result: "Invalid path parameter: Path parameter 'file_id' must not contain path separators"
# after
result = await call_mcp_tool(server_id="myapi", tool_name="get_file", arguments={"file_id": "readme.md"}) Defensive patterns
Strategy: validation
Validate before calling
def is_single_path_segment(value: object) -> bool:
s = "" if value is None else str(value)
return s != "" and "/" not in s and "\\" not in s
assert is_single_path_segment(args["file_id"]), "file_id must be one URL segment" Type guard
from typing import TypeGuard
def is_safe_path_segment(value: object) -> TypeGuard[str]:
if not isinstance(value, str) or not value:
return False
return "/" not in value and "\\" not in value and value not in (".", "..") Try / catch
try:
safe = _sanitize_path_parameter_value(value, name) # only if calling the generator directly
except ValueError as e:
raise BadRequest(str(e)) from None
# via the REST API: treat a tool result starting with "Invalid path parameter:" as a client-side 4xx Prevention
- Type tool inputs upstream: derive args from parsed/normalized values, never raw user strings.
- Validate every path-typed argument with the single-segment guard before sending it to the proxy.
- Map tool results starting with 'Invalid path parameter:' to your own 400, do not retry them.
When it happens
Trigger: Calling an MCP tool generated from an OpenAPI spec with a path parameter whose value contains / or \, e.g. arguments={"file_id": "docs/readme"} for path /files/{file_id}; passing a Windows path (C:\x\y) or a value whose str() contains separators (a list ['a','b'] stringifies to a/b).
Common situations: Passing filenames with directories or Windows paths to REST-backed MCP tools; passing a full URL where only one segment was expected; passing non-string values (lists, objects) whose string form contains slashes; porting curl examples that embed slashes into tool args.
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
- Path parameter '{param_name}' cannot include '.' or '..' seg
- {field_name} cannot be a dot path segment
- Invalid identifier {identifier!r}: path traversal detected
- {field_name} is required
- OpenAPI spec not found at {filepath}
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/6e13ada45a32e004.
Report an issue: GitHub.