BerriAI/litellm · error · LangFlowError
flow_id cannot be set via request parameters; use model lang
Error message
flow_id cannot be set via request parameters; use model langflow/{flow_id} What it means
LiteLLM's LangFlow integration extracts the target flow exclusively from the model string ('langflow/{flow_id}'). Passing flow_id as a request parameter (e.g. in extra_body or kwargs, which land in optional_params) is rejected with HTTP 400 because it would let a caller redirect a shared API key to a different flow. The check happens in _get_flow_id before any HTTP request is made.
Source
Thrown at litellm/llms/langflow/chat/transformation.py:75
def map_openai_params(
self,
non_default_params: dict,
optional_params: dict,
model: str,
drop_params: bool,
) -> dict:
return optional_params
def _get_flow_id(self, model: str, optional_params: dict) -> str:
"""
Extract flow_id from the authorized model name only.
Model format: "langflow/{flow_id}". Request kwargs must not override
flow_id (would allow calling another flow with the same API key).
"""
if optional_params.get("flow_id") is not None:
raise LangFlowError(
status_code=400,
message=("flow_id cannot be set via request parameters; use model langflow/{flow_id}"),
)
flow_id: Final = (model.split("/", 1)[1] if "/" in model else model).strip()
if not flow_id:
raise LangFlowError(
status_code=400,
message="flow_id is required; use model langflow/{flow_id}",
)
return flow_id
def get_complete_url(
self,
api_base: str | None,
api_key: str | None,
model: str,
optional_params: dict,View on GitHub (pinned to 6c2dcb801b)
Solutions
- Remove flow_id from the request kwargs / extra_body and encode it in the model name: model="langflow/{flow_id}"
- If using a router, check default_params and extra_body templates for a stale flow_id entry
- Verify no middleware or OpenAI-compatible shim is injecting flow_id into the payload
Example fix
# before litellm.completion(model="langflow/abc-123", messages=msgs, flow_id="abc-123") # after litellm.completion(model="langflow/abc-123", messages=msgs)
Defensive patterns
Strategy: validation
Validate before calling
def safe_langflow_call(model: str, extra_body: dict | None = None) -> None:
if "/" not in model or not model.split("/", 1)[1].strip():
raise ValueError(f"model must be langflow/{{flow_id}}, got: {model!r}")
body = extra_body or {}
if "flow_id" in body:
raise ValueError("flow_id must not be passed via extra_body; encode it in the model name") Type guard
def is_valid_langflow_model(model: str) -> bool:
return isinstance(model, str) and len(model.split("/", 1)) == 2 and bool(model.split("/", 1)[1].strip()) Try / catch
from litellm.llms.langflow.chat.transformation import LangFlowError
try:
litellm.completion(model=f"langflow/{flow_id}", messages=msgs)
except LangFlowError as e:
if e.status_code == 400 and "flow_id cannot be set" in str(e):
# strip flow_id from kwargs and retry once with model-only routing
... Prevention
- Centralize model-string construction: always f"langflow/{flow_id}" from a config lookup, never accept flow_id from request bodies
- Lint router default_params / extra_body templates for forbidden keys (flow_id, tweaks)
- Document for API consumers that langflow models take no provider-specific body params
When it happens
Trigger: Calling litellm.completion(model="langflow/my-flow", ..., flow_id="other-flow"), or passing flow_id via extra_body={'flow_id': ...}, api_key-level defaults, or router default_params that inject flow_id into optional_params.
Common situations: Migrating from a client that sent flow_id as a body parameter directly to the LangFlow REST API; putting flow_id in a router's default_params so it gets merged into every request; a generic OpenAI-compatible wrapper forwarding all kwargs.
Related errors
- tweaks cannot be set via request parameters; they would over
- flow_id is required; use model langflow/{flow_id}
- litellm_params is required for LangFlowA2AConfig (must conta
- Invalid file path {file_path!r}: path traversal detected
- Event hook {hook} is not in the supported event hooks {suppo
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/548149a0db888216.
Report an issue: GitHub.