bytedance/deer-flow · error · HTTPException
str(exc)
Error message
str(exc)
What it means
HTTP 422 raised when validate_thread_id rejects the thread_id on a run launch (shared by HTTP and internal launch paths). The ValueError text from the validator becomes the detail, naming the concrete format problem. Thread ids must match the gateway's expected id format before any run is created.
Source
Thrown at backend/app/gateway/services.py:1069
body: RunCreateRequest,
thread_id: str,
request: Request,
) -> RunRecord:
"""Create a RunRecord and launch the background agent task.
Parameters
----------
body : RunCreateRequest
The validated request body shared by HTTP and internal launch paths.
thread_id : str
Target thread.
request : Request
FastAPI request — used to retrieve singletons from ``app.state``.
"""
try:
validate_thread_id(thread_id)
except ValueError as exc:
raise HTTPException(status_code=422, detail=str(exc)) from exc
body_config = getattr(body, "config", None)
config_metadata = body_config.get("metadata") if isinstance(body_config, dict) else None
try:
validate_run_metadata_secrets(getattr(body, "metadata", None))
validate_run_metadata_secrets(config_metadata)
except LegacyRunMetadataSecretError as exc:
raise HTTPException(status_code=422, detail=str(exc)) from exc
stream_modes = normalize_stream_modes(body.stream_mode)
bridge = get_stream_bridge(request)
run_mgr = get_run_manager(request)
run_ctx = get_run_context(request)
disconnect = DisconnectMode.cancel if body.on_disconnect == "cancel" else DisconnectMode.continue_
body_context = getattr(body, "context", None) or {}
model_name = body_context.get("model_name")View on GitHub (pinned to 1dd6ba1acb)
Solutions
- Create the thread through the threads API first and use the returned id verbatim for runs.
- Read the detail string — it is the validator's own message describing the expected format.
- Validate/normalize ids client-side (no whitespace, correct casing) before sending.
Example fix
# before
runs.post("/threads/my-thread/runs", payload)
# after
thread = threads.post({}) # gateway assigns a valid id
runs.post(f"/threads/{thread.thread_id}/runs", payload) Defensive patterns
Strategy: validation
Validate before calling
const thread = await fetch('/api/threads', {method: 'POST'}).then(r => r.json());
const tid = thread.thread_id; // use gateway-issued id only Type guard
const isServerIssuedThreadId = (id: unknown): id is string =>
typeof id === 'string' && id.length > 0 && /^[0-9a-fA-F-]+$/.test(id) && !id.includes(' '); Try / catch
catch 422 on run creation; the detail carries the validator's format message — fix the id (usually by creating the thread properly) rather than retrying.
Prevention
- Never mint thread ids client-side; create threads via the API.
- Pass ids through verbatim without trimming/re-encoding.
- On 422, read the detail: it states the expected id format.
When it happens
Trigger: Creating a run with a thread id of the wrong shape/length/charset — e.g. a client-generated random string that violates the id format, an empty id, or an id with characters the validator forbids.
Common situations: Clients minting their own thread ids instead of creating threads via the API; URL-decoded ids that lost/gained characters; porting code from another platform with laxer id rules.
Related errors
- unsupported_run_option
- unsupported_stream_mode
- Invalid agent name '{name}'. Must match ^[A-Za-z0-9-]+$ (let
- Unknown model '{model}'. Use a model name defined under `mod
- Password is too common; choose a stronger password.
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/553e574449f6f236.
Report an issue: GitHub.