vxcontrol/pentagi · warning
no subtasks found for task %d: %w
Error message
no subtasks found for task %d: %w
What it means
Returned when GetTaskSubtasks succeeds but returns zero rows for the task, wrapped together with the sentinel ErrNothingToLoad. It signals there are no subtasks to restore into workers — the task has no plan generated yet (or its subtasks were never created).
Source
Thrown at backend/pkg/controller/subtasks.go:52
func NewSubtaskController(taskCtx *TaskContext) SubtaskController {
return &subtaskController{
mx: &sync.Mutex{},
taskCtx: taskCtx,
subtasks: make(map[int64]SubtaskWorker),
}
}
func (stc *subtaskController) LoadSubtasks(ctx context.Context, taskID int64, updater TaskUpdater) error {
stc.mx.Lock()
defer stc.mx.Unlock()
subtasks, err := stc.taskCtx.DB.GetTaskSubtasks(ctx, taskID)
if err != nil {
return fmt.Errorf("failed to get subtasks for task %d: %w", taskID, err)
}
if len(subtasks) == 0 {
return fmt.Errorf("no subtasks found for task %d: %w", taskID, ErrNothingToLoad)
}
for _, subtask := range subtasks {
st, err := LoadSubtaskWorker(ctx, subtask, stc.taskCtx, updater)
if err != nil {
if errors.Is(err, ErrNothingToLoad) {
continue
}
return fmt.Errorf("failed to create subtask worker: %w", err)
}
stc.subtasks[subtask.ID] = st
}
return nil
}
View on GitHub (pinned to ea665308ba)
Solutions
- Check errors.Is(err, ErrNothingToLoad) at the call site and, if so, call GenerateSubtasks instead of treating it as a hard failure.
- Verify the task actually has subtasks in the DB (SELECT * FROM subtasks WHERE task_id = ...) before resuming.
- If subtasks were deleted unintentionally, re-generate them via the flow's generate-plan path.
Example fix
// before
if err := stc.LoadSubtasks(ctx, taskID, updater); err != nil {
return err
}
// after
if err := stc.LoadSubtasks(ctx, taskID, updater); err != nil {
if errors.Is(err, ErrNothingToLoad) {
return stc.GenerateSubtasks(ctx)
}
return err
} Defensive patterns
Strategy: fallback
Validate before calling
n, err := db.GetTaskSubtaskCount(ctx, taskID)
if err == nil && n == 0 {
// nothing to load — generate instead
} Type guard
func isNothingToLoad(err error) bool {
return errors.Is(err, controller.ErrNothingToLoad)
} Try / catch
if err := stc.LoadSubtasks(ctx, taskID, updater); err != nil {
if isNothingToLoad(err) {
return stc.GenerateSubtasks(ctx) // fallback: create a plan
}
return err
} Prevention
- Check for ErrNothingToLoad explicitly instead of string-matching error text.
- Only resume flows that have progressed past plan generation.
- Call GenerateSubtasks as the fallback when a task has no subtasks yet.
- Never hard-fail a resume on an empty subtask list — it's a normal state.
When it happens
Trigger: subtaskController.LoadSubtasks is called for a taskID whose subtasks table rows are empty — e.g. resuming a flow before GenerateSubtasks ever ran, or after all subtasks were deleted.
Common situations: Server restart while a task was still in 'created' state with no generated plan; calling the resume/load API on a freshly created flow; a prior GenerateSubtasks failure left the task with no subtasks.
Related errors
- failed to get flow agent log: %w
- flow not found
- flow already stopped
- failed to update subtask %d status to created: %w
- subtask %d has created yet: %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/4820cc0b053b5aa3.
Report an issue: GitHub.