{"record":{"id":"7ace105114da8cea","repo":"bytedance/deer-flow","slug":"thread-not-found","errorCode":null,"errorMessage":"Thread not found","messagePattern":"Thread not found","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"warning","filePath":"backend/app/gateway/routers/scheduled_tasks.py","lineNumber":83,"sourceCode":"    return await repo.list_by_user(str(user.id))\n\n\n@router.post(\"/scheduled-tasks\")\n@require_permission(\"threads\", \"write\")\nasync def create_scheduled_task(request: Request, body: ScheduledTaskCreateRequest):\n    config = get_config()\n    repo = get_scheduled_task_repo(request)\n    thread_store = get_thread_store(request)\n    user = await get_optional_user_from_request(request)\n    if user is None:\n        raise HTTPException(status_code=401, detail=\"Authentication required\")\n    if body.context_mode not in {\"fresh_thread_per_run\", \"reuse_thread\"}:\n        raise HTTPException(status_code=422, detail=\"Unsupported context_mode\")\n    if body.context_mode == \"reuse_thread\":\n        if not body.thread_id:\n            raise HTTPException(status_code=422, detail=\"reuse_thread requires thread_id\")\n        if not await thread_store.check_access(body.thread_id, str(user.id), require_existing=True):\n            raise HTTPException(status_code=404, detail=\"Thread not found\")\n    if body.schedule_type not in {\"once\", \"cron\"}:\n        raise HTTPException(status_code=422, detail=\"Unsupported schedule_type\")\n\n    schedule_spec = dict(body.schedule_spec)\n    try:\n        validate_timezone(body.timezone)\n        if body.schedule_type == \"cron\":\n            raw_cron = schedule_spec.get(\"cron\")\n            if not isinstance(raw_cron, str):\n                raise HTTPException(status_code=422, detail=\"cron schedule requires schedule_spec.cron\")\n            schedule_spec[\"cron\"] = normalize_cron_expression(raw_cron)\n        next_run_at = compute_next_run_at(\n            body.schedule_type,\n            schedule_spec,\n            body.timezone,\n            now=datetime.now(UTC),\n        )\n    except ValueError as exc:","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/app/gateway/routers/scheduled_tasks.py#L65-L101","documentation":"Raised as HTTP 404 by POST /api/scheduled-tasks in reuse_thread mode when thread_store.check_access(thread_id, user_id, require_existing=True) fails — the thread does not exist, or exists but is not accessible/owned by the requesting user. Deliberately 404 (not 403) to avoid leaking thread existence.","triggerScenarios":"Creating a reuse_thread task with a deleted thread id, another user's thread id, or a malformed id.","commonSituations":"Thread was deleted before the task was created; switching accounts; stale thread id cached in the UI.","solutions":["Verify the thread exists and is owned by (or shared with) the current user via the threads endpoint.","Use a fresh, valid thread id, or switch context_mode to fresh_thread_per_run.","Re-check ownership if the thread belongs to a different user — access is enforced here."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"threads = requests.get(f\"{BASE}/api/threads\", headers=auth).json()\nowned = {t[\"id\"] for t in threads.get(\"threads\", [])}\nassert body[\"thread_id\"] in owned, \"thread missing or not accessible for this user\"","typeGuard":"const isAccessibleThread = (tid: string, ownedIds: Set<string>): boolean => ownedIds.has(tid);","tryCatchPattern":"resp = requests.post(f\"{BASE}/api/scheduled-tasks\", json=body, headers=auth)\nif resp.status_code == 404 and body[\"context_mode\"] == \"reuse_thread\":\n    body[\"thread_id\"] = await pick_existing_thread()  # recover\n    resp = requests.post(f\"{BASE}/api/scheduled-tasks\", json=body, headers=auth)","preventionTips":["Offer only currently accessible threads in the task-creation picker.","Remember 404 here can mean 'not yours', not just 'missing' — don't leak existence assumptions to users.","Refresh the thread list when the picker opens."],"tags":["scheduled-tasks","threads","http-404","ownership"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}