bytedance/deer-flow · error · HTTPException
Authentication required
Error message
Authentication required
What it means
Raised as HTTP 401 by POST /api/scheduled-tasks when get_optional_user_from_request returns None — the request arrived without valid authentication credentials. The route decorator checks the threads:write permission first, but an anonymous request fails this explicit user check.
Source
Thrown at backend/app/gateway/routers/scheduled_tasks.py:76
@router.get("/scheduled-tasks")
@require_permission("threads", "read")
async def list_scheduled_tasks(request: Request):
repo = get_scheduled_task_repo(request)
user = await get_optional_user_from_request(request)
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)View on GitHub (pinned to 1dd6ba1acb)
Solutions
- Authenticate first (log in via the auth flow the deployment uses) and attach the token/cookie to the request.
- Verify the token is unexpired and issued for this Gateway instance.
- Ensure cookies are sent cross-origin (credentials: 'include', CORS allows it).
Example fix
# before
requests.post(f"{BASE}/api/scheduled-tasks", json=body) # 401
# after
requests.post(f"{BASE}/api/scheduled-tasks", json=body,
headers={"Authorization": f"Bearer {token}"}) Defensive patterns
Strategy: validation
Validate before calling
assert auth_token, "no token available; authenticate before creating scheduled tasks"
probe = requests.get(f"{BASE}/api/scheduled-tasks", headers={"Authorization": f"Bearer {auth_token}"})
assert probe.status_code != 401, "token invalid or expired" Try / catch
resp = requests.post(f"{BASE}/api/scheduled-tasks", json=body, headers=auth)
if resp.status_code == 401:
token = refresh_credentials()
resp = requests.post(f"{BASE}/api/scheduled-tasks", json=body,
headers={"Authorization": f"Bearer {token}"}) Prevention
- Always attach credentials to scheduled-task requests — there is no anonymous mode.
- Refresh tokens proactively before expiry windows.
- Include credentials in cross-origin fetches (credentials: 'include').
When it happens
Trigger: Creating a scheduled task with no Authorization header, an expired/invalid token, or a token from a disabled user; the permission decorator may pass in permissive setups, then the user check fails.
Common situations: Scripting the API without first obtaining a session/token; frontend token expired; auth cookie not sent on a cross-origin request.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/7565db82452e9c04.
Report an issue: GitHub.