odysseus-dev/odysseus · warning · HTTPException
Prompt is required for LLM/research tasks
Error message
Prompt is required for LLM/research tasks
What it means
Create-task validation: task_type 'llm' or 'research' requires a non-empty prompt field. These types execute an LLM prompt, so a blank prompt is rejected with HTTP 400 before any scheduling logic runs.
Source
Thrown at routes/task_routes.py:457
if not target_id:
return None
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")View on GitHub (pinned to f9235ebbf1)
Solutions
- Include a non-empty prompt in the request body for llm/research tasks.
- Add client-side required-field validation on the prompt input before submit.
- Check for field-name typos in the payload against the TaskCreate schema (it must be 'prompt').
Example fix
// before
await api.createTask({task_type: 'llm', trigger_type: 'event', trigger_event: 'x'});
// after
const prompt = promptInput.value.trim();
if (!prompt) return showError('Prompt is required');
await api.createTask({task_type: 'llm', prompt, trigger_type: 'event', trigger_event: 'x'}); Defensive patterns
Strategy: validation
Validate before calling
function validateTaskCreate(p) {
if ((p.task_type === 'llm' || p.task_type === 'research') && !(p.prompt ?? '').trim())
throw new ValidationError('Prompt is required for LLM/research tasks');
return p;
} Type guard
function isLlmLikeTask(t: unknown): t is {task_type: 'llm'|'research'} {
return typeof t === 'object' && t !== null &&
['llm','research'].includes((t as any).task_type);
} Prevention
- Make prompt a required input in the form for llm/research types (disable submit while empty).
- Mirror the server's conditional-required rules in a shared schema (zod/pydantic export).
When it happens
Trigger: POST /api/tasks with {"task_type": "llm"} or {"task_type": "research"} and prompt null/empty/whitespace.
Common situations: Frontend sends the form before the user types a prompt; prompt field name mismatch (e.g. 'text' vs 'prompt'); API client defaulting prompt to empty string; importing tasks from JSON where the prompt key was dropped.
Related errors
- Task cannot chain to itself
- Action name is required for action 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/acee04498d0660a8.
Report an issue: GitHub.