bytedance/deer-flow · warning · HTTPException

reuse_thread requires thread_id

Error message

reuse_thread requires thread_id

What it means

Raised as HTTP 422 by POST /api/scheduled-tasks when context_mode is 'reuse_thread' but the optional thread_id field is null/omitted. Reusing a thread requires identifying which thread to continue.

Source

Thrown at backend/app/gateway/routers/scheduled_tasks.py:81

    if user is None:
        return []
    return await repo.list_by_user(str(user.id))


@router.post("/scheduled-tasks")
@require_permission("threads", "write")
async def create_scheduled_task(request: Request, body: ScheduledTaskCreateRequest):
    config = get_config()
    repo = get_scheduled_task_repo(request)
    thread_store = get_thread_store(request)
    user = await get_optional_user_from_request(request)
    if user is None:
        raise HTTPException(status_code=401, detail="Authentication required")
    if body.context_mode not in {"fresh_thread_per_run", "reuse_thread"}:
        raise HTTPException(status_code=422, detail="Unsupported context_mode")
    if body.context_mode == "reuse_thread":
        if not body.thread_id:
            raise HTTPException(status_code=422, detail="reuse_thread requires thread_id")
        if not await thread_store.check_access(body.thread_id, str(user.id), require_existing=True):
            raise HTTPException(status_code=404, detail="Thread not found")
    if body.schedule_type not in {"once", "cron"}:
        raise HTTPException(status_code=422, detail="Unsupported schedule_type")

    schedule_spec = dict(body.schedule_spec)
    try:
        validate_timezone(body.timezone)
        if body.schedule_type == "cron":
            raw_cron = schedule_spec.get("cron")
            if not isinstance(raw_cron, str):
                raise HTTPException(status_code=422, detail="cron schedule requires schedule_spec.cron")
            schedule_spec["cron"] = normalize_cron_expression(raw_cron)
        next_run_at = compute_next_run_at(
            body.schedule_type,
            schedule_spec,
            body.timezone,
            now=datetime.now(UTC),

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Include the target thread's id: {"context_mode": "reuse_thread", "thread_id": "..."}.
  2. Or use "fresh_thread_per_run" if continuing an existing thread is not intended.
  3. Get a valid thread id from the threads listing endpoint if unsure.

Example fix

// before
{ "context_mode": "reuse_thread" }
// after
{ "context_mode": "reuse_thread", "thread_id": "thr-abc123" }
Defensive patterns

Strategy: validation

Validate before calling

if body["context_mode"] == "reuse_thread":
    assert body.get("thread_id"), "reuse_thread requires a non-empty thread_id"

Type guard

const isReusableThreadRequest = (b: CreateTaskBody): b is CreateTaskBody & { thread_id: string } =>
  b.context_mode === "reuse_thread" && typeof b.thread_id === "string" && b.thread_id.length > 0;

Prevention

When it happens

Trigger: Creating a task with {"context_mode": "reuse_thread"} and no thread_id in the body.

Common situations: Client defaults thread_id to null and switches context_mode at runtime; copying a payload template without filling thread_id.

Related errors


AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14). Data as JSON: /api/errors/4cd802515ddbfab8. Report an issue: GitHub.