odysseus-dev/odysseus · warning · HTTPException
Action name is required for action tasks
Error message
Action name is required for action tasks
What it means
Create-task validation: task_type 'action' requires a non-empty action name naming a built-in or registered action. Rejected with HTTP 400 before the admin-privilege check for admin-only actions runs.
Source
Thrown at routes/task_routes.py:459
if current_task_id and target_id == current_task_id:
raise HTTPException(400, "Task cannot chain to itself")
q = db.query(ScheduledTask).filter(ScheduledTask.id == target_id)
if user:
q = q.filter(ScheduledTask.owner == user)
target = q.first()
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")View on GitHub (pinned to f9235ebbf1)
Solutions
- Set action to a valid action name (see BUILTIN_ACTION_INFO keys served by the actions listing endpoint).
- Make the client action selector required and disable submit until a real action is chosen.
- If the action name comes from a config, verify it matches a key in src.builtin_actions.BUILTIN_ACTION_INFO.
Example fix
// before
await api.createTask({task_type: 'action'}); // no action
// after
if (!actionSelect.value) return showError('Pick an action');
await api.createTask({task_type: 'action', action: actionSelect.value}); Defensive patterns
Strategy: validation
Validate before calling
function validateActionTask(p) {
if (p.task_type === 'action' && !(p.action ?? '').trim())
throw new ValidationError('Action name is required');
return p;
} Type guard
function hasActionName(p: unknown): p is {task_type: 'action'; action: string} {
return typeof p === 'object' && p !== null &&
(p as any).task_type === 'action' &&
typeof (p as any).action === 'string' && (p as any).action.length > 0;
} Prevention
- Require a non-placeholder selection in the action dropdown before enabling submit.
- Validate the action name against BUILTIN_ACTION_INFO keys fetched from the server.
When it happens
Trigger: POST /api/tasks with {"task_type": "action"} and action null/empty/whitespace.
Common situations: Action dropdown left on its placeholder option whose value is ''; action key renamed between versions so the client sends the old empty default; JSON import missing the action field.
Related errors
- Task cannot chain to itself
- Prompt is required for LLM/research tasks
- Schedule is required for schedule-triggered tasks
- Cron expression is required for cron schedule
- Invalid cron expression
AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14).
Data as JSON: /api/errors/e8451b36e200642a.
Report an issue: GitHub.