{"record":{"id":"9b10ce641547a63c","repo":"bytedance/deer-flow","slug":"once-schedule-must-be-in-the-future","errorCode":null,"errorMessage":"once schedule must be in the future","messagePattern":"once schedule must be in the future","errorType":"http","errorClass":"HTTPException","httpStatus":422,"severity":"warning","filePath":"backend/app/gateway/routers/scheduled_tasks.py","lineNumber":105,"sourceCode":"    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:\n        raise HTTPException(status_code=422, detail=str(exc)) from exc\n\n    if body.schedule_type == \"once\" and next_run_at is None:\n        raise HTTPException(status_code=422, detail=\"once schedule must be in the future\")\n    if body.schedule_type == \"once\" and next_run_at is not None and (next_run_at - datetime.now(UTC)).total_seconds() < config.scheduler.min_once_delay_seconds:\n        raise HTTPException(\n            status_code=422,\n            detail=(f\"once schedule must be at least {config.scheduler.min_once_delay_seconds} seconds in the future\"),\n        )\n\n    return await repo.create(\n        task_id=f\"task-{uuid.uuid4().hex}\",\n        user_id=str(user.id),\n        thread_id=body.thread_id,\n        context_mode=body.context_mode,\n        assistant_id=\"lead_agent\",\n        title=body.title,\n        prompt=body.prompt,\n        schedule_type=body.schedule_type,\n        schedule_spec=schedule_spec,\n        timezone=body.timezone,\n        next_run_at=next_run_at,","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/app/gateway/routers/scheduled_tasks.py#L87-L123","documentation":"Raised as HTTP 422 by POST /api/scheduled-tasks when schedule_type is 'once' but compute_next_run_at returned None — the requested run time is not in the future (or could not produce a future occurrence). Once-schedules must resolve to a future instant.","triggerScenarios":"A once schedule whose run_at is in the past or exactly now, or a spec from which no future time can be computed.","commonSituations":"Client sends a hardcoded timestamp; clock skew between client and server; user picks 'now' in a datetime picker.","solutions":["Set the once run_at to a strictly future instant (server-side UTC is authoritative).","Compute the timestamp at request time rather than reusing a cached value.","Correct significant client/server clock skew (NTP) if the value should be future."],"exampleFix":"// before\n{ \"schedule_type\": \"once\", \"schedule_spec\": { \"run_at\": \"2026-01-01T00:00:00Z\" } }\n// after\nconst runAt = new Date(Date.now() + 10 * 60_000).toISOString();\n{ \"schedule_type\": \"once\", \"schedule_spec\": { \"run_at\": runAt } }","handlingStrategy":"validation","validationCode":"from datetime import datetime, UTC\nrun_at = datetime.fromisoformat(body[\"schedule_spec\"][\"run_at\"].replace(\"Z\", \"+00:00\"))\nassert run_at > datetime.now(UTC) + timedelta(seconds=1), \"once run_at must be strictly in the future\"","typeGuard":"const isFutureRunAt = (iso: string): boolean =>\n  Date.parse(iso) > Date.now();","tryCatchPattern":null,"preventionTips":["Compute run_at at submit time, never reuse cached timestamps.","Disable 'now' and past datetimes in the picker.","Keep server clocks NTP-synced to avoid skew-induced rejections."],"tags":["scheduled-tasks","validation","http-422","time"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}