odysseus-dev/odysseus · warning · HTTPException
Schedule is required for schedule-triggered tasks
Error message
Schedule is required for schedule-triggered tasks
What it means
Create-task validation: when trigger_type is 'schedule', the schedule sub-type must be provided (values such as 'once', daily-style schedules, or 'cron' — as consumed by compute_next_run). Missing schedule means next_run cannot be computed, so the request fails with HTTP 400.
Source
Thrown at routes/task_routes.py:465
if not target:
raise HTTPException(404, "Chained task not found")
return target.id
@router.post("")
async def create_task(request: Request, req: TaskCreate):
user = _owner(request)
# Validate
if req.task_type in ("llm", "research") and not req.prompt:
raise HTTPException(400, "Prompt is required for LLM/research tasks")
if req.task_type == "action" and not req.action:
raise HTTPException(400, "Action name is required for action tasks")
# Block shell-executing action types for non-admins. action_run_local
# uses subprocess.run(shell=True) and ssh_command / run_script run
# arbitrary commands.
_require_admin_for_task_action(user, req.task_type, req.action)
if req.trigger_type == "schedule" and not req.schedule:
raise HTTPException(400, "Schedule is required for schedule-triggered tasks")
if req.trigger_type == "schedule" and req.schedule == "cron" and not req.cron_expression:
raise HTTPException(400, "Cron expression is required for cron schedule")
if req.trigger_type == "schedule" and req.schedule == "cron" and req.cron_expression:
try:
from croniter import croniter
croniter(req.cron_expression)
except Exception:
raise HTTPException(400, "Invalid cron expression")
if req.trigger_type == "event" and not req.trigger_event:
raise HTTPException(400, "Event name is required for event-triggered tasks")
if req.trigger_type == "event" and not req.trigger_count:
raise HTTPException(400, "Trigger count is required for event-triggered tasks")
# Auto-generate name
name = req.name
if not name:
if req.task_type == "action":
from src.builtin_actions import BUILTIN_ACTION_INFOView on GitHub (pinned to f9235ebbf1)
Solutions
- Include a valid schedule value (e.g. 'once' with scheduled_date, or 'cron' with cron_expression) whenever trigger_type is 'schedule'.
- Make the schedule field conditionally required in the client form when trigger_type === 'schedule'.
- Cross-check the TaskCreate schema for the accepted schedule enum values and send one of those exactly.
Example fix
// before
{task_type: 'llm', prompt, trigger_type: 'schedule'}
// after
{task_type: 'llm', prompt, trigger_type: 'schedule', schedule: 'cron', cron_expression: '0 9 * * *'} Defensive patterns
Strategy: validation
Validate before calling
function validateSchedule(p) {
if (p.trigger_type === 'schedule' && !p.schedule)
throw new ValidationError('Schedule is required for schedule-triggered tasks');
return p;
} Type guard
function isScheduleTrigger(p: unknown): p is {trigger_type: 'schedule'; schedule: string} {
return typeof p === 'object' && p !== null &&
(p as any).trigger_type === 'schedule' &&
typeof (p as any).schedule === 'string' && (p as any).schedule.length > 0;
} Prevention
- Bind the schedule picker to the payload and mark it required when trigger_type is 'schedule'.
- Keep a single shared enum of schedule values between client and server.
When it happens
Trigger: POST /api/tasks with {"trigger_type": "schedule"} and schedule null/empty; or a schedule string that is falsy after Pydantic defaults.
Common situations: Frontend schedule picker not bound to the payload; partial update JSON that sets trigger_type but omits schedule; schedule value sent as 'none'/None casing mismatch leaving it empty.
Related errors
- Cron expression is required for cron schedule
- Task cannot chain to itself
- Prompt is required for LLM/research tasks
- Action name is required for action tasks
- Invalid cron expression
AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14).
Data as JSON: /api/errors/1911844d2d134c1a.
Report an issue: GitHub.