langflow-ai/langflow · warning · HTTPException
str(e)
Error message
str(e)
What it means
HTTP 400 from _create_flow's catch-all: the raised exception has an `errors` attribute — the signature of a Pydantic ValidationError (raised by Flow.model_validate / FlowRead.model_validate / field coercion inside creation). The exception's str() (which includes per-field error details) becomes the response detail, and genuine HTTPExceptions are re-raised before this branch.
Source
Thrown at src/backend/base/langflow/api/v1/flows_helpers.py:350
# Apply the stable ID: explicit flow_id param (PUT upsert) takes precedence,
# then flow.id (stable import from FlowCreate), then the uuid4 default.
effective_id = flow_id if flow_id is not None else flow.id
if effective_id is not None:
db_flow.id = effective_id
db_flow.updated_at = datetime.now(timezone.utc)
await _validate_and_assign_folder(session, db_flow, user_id)
session.add(db_flow)
await session.flush()
await session.refresh(db_flow)
await _save_flow_to_fs(db_flow, user_id, storage_service)
return FlowRead.model_validate(db_flow, from_attributes=True)
except Exception as e:
if hasattr(e, "errors"):
raise HTTPException(status_code=400, detail=str(e)) from e
if isinstance(e, HTTPException):
raise
logger.exception("Error creating flow")
raise HTTPException(status_code=500, detail="An internal error occurred while creating the flow.") from e
async def _read_flow(
session: AsyncSession,
flow_id: UUID,
user_id: UUID,
):
"""Read a flow.
When the registered authorization service supports cross-user fetch
(authorization plugin), the row is loaded by id alone and the caller's
``ensure_flow_permission`` decides access. Otherwise the query stays
owner-scoped so the OSS pass-through default cannot widen visibility.
"""View on GitHub (pinned to 976ec789d2)
Solutions
- Read the response detail: str(ValidationError) lists each failing field and reason — fix those fields.
- Validate the payload client-side against the FlowCreate schema before posting.
- If the error names a field you never sent, suspect server-side model coercion and check version mismatch between client schema and server.
Example fix
# before
{"name": "f", "data": [1, 2]} # data must be a dict
# after
{"name": "f", "data": {"nodes": [], "edges": []}} Defensive patterns
Strategy: validation
Validate before calling
if (typeof body.data !== 'object' || body.data === null || Array.isArray(body.data)) throw new Error('flow.data must be a dict'); Type guard
const isFlowData = (d: unknown): d is {nodes: unknown[]; edges: unknown[]} => typeof d === 'object' && d !== null && !Array.isArray(d) && 'nodes' in d && 'edges' in d; Try / catch
try { await createFlow(body) } catch (e) { if (e.status === 400 && e.detail.includes('validation')) showFieldErrors(e.detail); throw e; } Prevention
- Validate against the FlowCreate schema client-side
- Send data as a dict with nodes/edges arrays
- Parse the Pydantic error list in detail to fix exact fields
When it happens
Trigger: POST /api/v1/flows (or import/upsert paths calling _create_flow) with a payload that fails Pydantic validation during ORM->model conversion or field assignment — wrong types for flow.data, invalid datetime on updated_at handling, or a field constraint violated that request schema validation did not catch.
Common situations: data is a list or string instead of a dict; timestamps serialized in a non-ISO format; enum fields (e.g. flow style/visibility) given unknown values; sending null for a required field that the request model marks optional but the ORM model does not.
Related errors
- fs_path cannot be empty
- Folder not found
- Failed to install MCP
- Invalid path
- Provider '{provider}' is not configured. Available providers
AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14).
Data as JSON: /api/errors/adaf389680df8357.
Report an issue: GitHub.