BerriAI/litellm · error · ValueError
Path parameter '{param_name}' cannot include '.' or '..' seg
Error message
Path parameter '{param_name}' cannot include '.' or '..' segments What it means
Second guard in _sanitize_path_parameter_value in the OpenAPI-to-MCP generator: after the slash check, the value is parsed with PurePosixPath and any '.' or '..' segment raises this ValueError, preventing dot-segment traversal (e.g. a value of '..' escaping one path level). Because any '/' already raised the earlier error, this branch in practice fires for a parameter whose entire value is '..' (or a lone '.' in callers that pre-split segments). Like the sibling error it is returned as "Invalid path parameter: ..." on the generated tool path.
Source
Thrown at litellm/proxy/_experimental/mcp_server/openapi_to_mcp_generator.py:124
"_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."
)
except RuntimeError as e:
# "no running event loop" is fine; other RuntimeErrors we re-raise
if "no running event loop" not in str(e).lower():View on GitHub (pinned to 77b7c6c40c)
Solutions
- Pass a concrete segment value, never a dot-relative path component.
- If the value comes from filesystem logic, resolve it (Path(x).resolve().name) or validate it before sending it to the tool.
- Treat this error text in a tool result as untrusted-input feedback: reject the caller's input in your own app with a 4xx rather than retrying.
Example fix
# before
parent = os.path.join(base, "..") # leaks '..'
await call_mcp_tool(server_id="fs", tool_name="list_dir", arguments={"path": parent})
# after
parent = os.path.basename(os.path.normpath(os.path.join(base, "..")))
await call_mcp_tool(server_id="fs", tool_name="list_dir", arguments={"path": parent}) Defensive patterns
Strategy: validation
Validate before calling
def has_no_dot_segments(value: object) -> bool:
s = "" if value is None else str(value)
if "/" in s or "\\" in s:
return False
return s not in (".", "..")
assert has_no_dot_segments(args[name]), f"{name} must be a concrete 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)
except ValueError as e:
raise BadRequest(str(e)) from None
# REST callers: a result string "Invalid path parameter: Path parameter 'x' cannot include '.' or '..' segments" is a permanent 4xx Prevention
- Never feed os.path/pathlib intermediates ('..', '.') into tool arguments; resolve them first.
- Reject dot-segment values in your API layer with your own 400 before they reach the proxy.
- Add unit tests for path-typed tool args covering '..', '.', and backslash variants.
When it happens
Trigger: Calling a generated MCP tool with a path parameter value of exactly ".." (or ".") for a path like /files/{parent}/items/{name}; commonly happens when a caller computes the parent segment with os.path and accidentally passes the '..' produced by a relative path.
Common situations: Defaulted/empty-optional arguments that fall back to '..'; path manipulation code (os.path.join, pathlib) leaking dot segments into tool args; test fixtures that use '..' as a sentinel ID.
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}' must not contain path separato
- Invalid identifier {identifier!r}: path traversal detected
- {field_name} cannot be a dot path segment
- OpenAPI spec not found at {filepath}
- MCP server for tool '{name}' is not available; refusing to d
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/619a654c1bf0b898.
Report an issue: GitHub.