BerriAI/litellm · warning · ManagementProblem
urn:litellm:error:unknown-query-parameter
urn:litellm:error:unknown-query-parameter
Error message
Unrecognized query parameter(s): {', '.join(unknown)}. What it means
The same unknown-query-parameter problem, raised from the shared list framework: handle_list() first builds a query plan via build_query_plan, which returns a ProblemDetail when it finds query names outside the spec's allowed set (including the route's scoping params), and line 515 converts that plan-problem into a ManagementProblem. Every /management/v1 list endpoint built on handle_list (budgets, keys, teams, ...) funnels through this single raise.
Source
Thrown at litellm/proxy/management_endpoints/management_v1/list_framework.py:515
take=page_size,
)
def _duplicate_params(request: Request) -> tuple[str, ...]:
names: Final = tuple(name for name, _ in request.query_params.multi_items())
return tuple(sorted(frozenset(name for name in names if names.count(name) > 1)))
async def handle_list(
spec: ListSpec[TRow, TOut],
executor: ListExecutor[TRow],
request: Request,
caller: UserAPIKeyAuth,
) -> ListResponse[TOut]:
"""Plan, execute, count, serialize, envelope. Failures reach the client as RFC 9457 problems."""
plan: Final = build_query_plan(spec=spec, params=request.query_params, caller=caller)
if isinstance(plan, ProblemDetail):
raise ManagementProblem(plan)
# Checked here rather than in build_query_plan because a Mapping[str, str] cannot
# represent a repeat: query_params.get() silently keeps the last one, so ?page=1&page=999
# would page from 999 without the caller ever being told which value won.
duplicates: Final = _duplicate_params(request)
if duplicates:
raise ManagementProblem(
_problem(
"duplicate-query-parameter",
"Duplicate query parameter",
400,
f"Repeated query parameter(s): {', '.join(duplicates)}. Each may appear once; "
f"use a comma-separated list for multiple sort keys or filter values.",
)
)
total_count: Final = await executor.count(plan.where)
rows: Final = await executor.find_many(plan)View on GitHub (pinned to 77b7c6c40c)
Solutions
- Send only parameters the endpoint declares: page, page_size, sort (comma-separated, '-' prefix for descending), search, and filter[<field>][op] names from its spec
- Read the problem's detail — it lists the unknown names and the allowed set for that exact route
- Pin your client SDK to a version matching the proxy release so allowed sets agree
- Never repeat a parameter (?page=1&page=2) — that raises the related duplicate-query-parameter 400 from the same handler
Example fix
# before curl 'http://localhost:4000/management/v1/keys?sort_dir=asc' # 400 via handle_list # after curl 'http://localhost:4000/management/v1/keys?sort=-token&page_size=25'
Defensive patterns
Strategy: validation
Validate before calling
from collections import Counter
def validate_list_query(q: dict) -> None:
ALLOWED = {'page', 'page_size', 'sort', 'search'} # per-route allowlist
unknown = set(q) - ALLOWED
if unknown:
raise ValueError(f'unknown params {sorted(unknown)}; allowed {sorted(ALLOWED)}')
dupes = [k for k, n in Counter(q).items() if n > 1] # only relevant if you build raw query strings
if dupes:
raise ValueError(f'params may appear once: {dupes}; use comma-separated values instead') Try / catch
try:
r = await client.get('/management/v1/keys', params=q)
r.raise_for_status()
except httpx.HTTPStatusError as e:
problem = e.response.json()
ptype = problem.get('type', '')
if ptype.endswith('unknown-query-parameter'):
q = {k: v for k, v in q.items() if k in ALLOWED} # strip and retry once
r = await client.get('/management/v1/keys', params=q)
elif ptype.endswith('duplicate-query-parameter'):
raise ValueError('send each param once; join multi-values with commas') from e
else:
raise Prevention
- Build URLs with a params dict — httpx/requests cannot accidentally duplicate keys that way
- Learn the framework's contract: page/page_size, sort='-field,field2', filter[field][op]=v, search=q
- Never forward arbitrary user-supplied query strings into management/v1 calls; filter them first
When it happens
Trigger: Any management/v1 list call with an undeclared parameter, e.g. ?sort_dir=asc instead of sort=..., ?model=gpt-4o on a route without a model filter, or a caller trying to override a server-scoped param like user_filter that only admins can set; also fires when params pass the route-level check but not the per-spec allowed set.
Common situations: Clients targeting params documented for a different list endpoint; assuming OpenAI-style pagination names (limit/offset) instead of page/page_size; version drift between the SDK's query builder and the deployed spec.
Related errors
- urn:litellm:error:unknown-query-parameter
- Please provide start_date and end_date
- Invalid sort order. Must be 'asc' or 'desc'
- urn:litellm:error:database-not-connected
- mcp_tools_config must be a list of dictionaries
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/bdc921fa9c55c95b.
Report an issue: GitHub.