BerriAI/litellm · error · HTTPException
400
400
Error message
Expected 1 model, got {len(target_model_names)} What it means
LiteLLM 'unified' file ids embed routing metadata (base64 of litellm_proxy:<purpose>;unified_id,...;target_model_names,<comma-separated models>). When POST /v1/batches receives such an id as input_file_id, the proxy parses target_model_names and must pick exactly one model to create the batch against; with a different count it returns HTTP 400 'Expected 1 model, got N'.
Source
Thrown at litellm/proxy/batches_endpoints/endpoints.py:282
)
response.input_file_id = input_file_id
elif litellm.enable_loadbalancing_on_batch_endpoints is True and is_router_model and router_model is not None:
if llm_router is None:
raise HTTPException(
status_code=500,
detail={"error": "LLM Router not initialized. Ensure models added to proxy."},
)
response = await llm_router.acreate_batch(**_create_batch_data)
elif (
unified_file_id and input_file_id
): # litellm_proxy:application/octet-stream;unified_id,c4843482-b176-4901-8292-7523fd0f2c6e;target_model_names,gpt-4o-mini
target_model_names: Final = get_models_from_unified_file_id(unified_file_id)
## EXPECTS 1 MODEL
if len(target_model_names) != 1:
raise HTTPException(
status_code=400,
detail={"error": f"Expected 1 model, got {len(target_model_names)}"},
)
model: Final = target_model_names[0]
_create_batch_data["model"] = model
resolved_storage_url: Final = await _resolve_managed_input_file_storage_url(input_file_id)
if resolved_storage_url is not None:
_create_batch_data["input_file_id"] = resolved_storage_url
if llm_router is None:
raise HTTPException(
status_code=500,
detail={"error": "LLM Router not initialized. Ensure models added to proxy."},
)
_create_batch_data.update(disable_fallbacks=True) # pyright: ignore[reportCallIssue] # router flag
response = await llm_router.acreate_batch(**_create_batch_data)View on GitHub (pinned to 77b7c6c40c)
Solutions
- Re-upload the input file scoped to exactly one target model and use that unified file id in the batch request.
- Create per-model file copies and one batch per model when several providers must run the same input.
- For load-balanced batching, send a router model name in the batch body with enable_loadbalancing_on_batch_endpoints instead of a multi-model file id.
Example fix
# before - file uploaded for two models, then used for a batch
curl -X POST "$PROXY/v1/files" -H "Authorization: Bearer $KEY" \
-F purpose=batch -F file=@input.jsonl -F 'target_model_names=gpt-4o-mini,gemini-2.0-flash'
curl -X POST "$PROXY/v1/batches" -H "Authorization: Bearer $KEY" \
-d '{"input_file_id": "<multi-model-unified-file-id>"}'
# after - one target model per file
curl -X POST "$PROXY/v1/files" -H "Authorization: Bearer $KEY" \
-F purpose=batch -F file=@input.jsonl -F 'target_model_names=gpt-4o-mini'
curl -X POST "$PROXY/v1/batches" -H "Authorization: Bearer $KEY" \
-d '{"input_file_id": "<single-model-file-id>"}' Defensive patterns
Strategy: validation
Validate before calling
import base64
def count_target_models(unified_file_id: str) -> int:
try:
raw = base64.b64decode(unified_file_id + '==').decode('utf-8', errors='ignore')
except Exception:
return 0
for part in raw.split(';'):
if part.startswith('target_model_names,'):
return len([m for m in part.split(',', 1)[1].split(',') if m.strip()])
return 0
# run before creating a batch
assert count_target_models(input_file_id) == 1, 'use a single-model unified file id' Type guard
import base64
def is_single_model_file_id(file_id: str) -> bool:
try:
raw = base64.b64decode(file_id + '==').decode('utf-8', errors='ignore')
except Exception:
return False
for part in raw.split(';'):
if part.startswith('target_model_names,'):
names = [m for m in part.split(',', 1)[1].split(',') if m.strip()]
return len(names) == 1
return False Try / catch
try:
batch = await client.batches.create(input_file_id=fid, ...)
except openai.BadRequestError as e:
if 'Expected 1 model' in str(e):
fid = await reupload_scoped_to_single_model() # re-upload with one target model
batch = await client.batches.create(input_file_id=fid, ...)
else:
raise Prevention
- Upload batch input files scoped to exactly one target_model_names value.
- Never reuse multi-model unified file ids (fan-out retrieval) as batch inputs.
- Assert the decoded id contains a single model before submitting the batch.
When it happens
Trigger: POST /v1/batches where input_file_id is a unified file id whose target_model_names lists 2+ models (file uploaded for multiple models) or encodes an empty model list.
Common situations: Reusing a multi-model upload (meant for unified file retrieval across providers) as batch input; copying file ids from fan-out workflow logs; hand-built batch payloads referencing shared files.
Related errors
- Cannot delete file {file_id}. The file is referenced by {cou
- Request arguments are required
- GitHub source must include 'repo' field (e.g., 'org/repo')
- URL source must include 'url' field (e.g., 'https://github.c
- git-subdir source must include 'url' field (e.g., 'https://g
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/62bc109b2ed06ef6.
Report an issue: GitHub.