vxcontrol/pentagi · error
failed to get task planned subtasks: %w
Error message
failed to get task planned subtasks: %w
What it means
PopSubtask fetches the next planned subtask for a task via GetTaskPlannedSubtasks under the controller mutex. This error wraps a read failure of that query. It is returned to the worker loop, so a persistent DB failure prevents any subtask from being dispatched.
Source
Thrown at backend/pkg/controller/subtasks.go:147
TaskID: stc.taskCtx.TaskID,
Title: info.Title,
Description: info.Description,
})
if err != nil {
return fmt.Errorf("failed to create subtask for task %d: %w", stc.taskCtx.TaskID, err)
}
}
return nil
}
func (stc *subtaskController) PopSubtask(ctx context.Context, updater TaskUpdater) (SubtaskWorker, error) {
stc.mx.Lock()
defer stc.mx.Unlock()
subtasks, err := stc.taskCtx.DB.GetTaskPlannedSubtasks(ctx, stc.taskCtx.TaskID)
if err != nil {
return nil, fmt.Errorf("failed to get task planned subtasks: %w", err)
}
if len(subtasks) == 0 {
return nil, nil
}
stdb := subtasks[0]
if st, ok := stc.subtasks[stdb.ID]; ok {
return st, nil
}
st, err := NewSubtaskWorker(ctx, stc.taskCtx, stdb.ID, stdb.Title, stdb.Description, updater)
if err != nil {
return nil, fmt.Errorf("failed to create subtask worker: %w", err)
}
stc.subtasks[stdb.ID] = st
View on GitHub (pinned to ea665308ba)
Solutions
- Check the wrapped cause — connection errors warrant DB restart/reconnect handling
- Distinguish context.Canceled from real DB errors and treat cancellation as benign
- Ensure connection pool size matches number of concurrent flow workers
- Retry PopSubtask; it holds a mutex so it is safe to call again
Example fix
// before
subtasks, err := stc.taskCtx.DB.GetTaskPlannedSubtasks(ctx, stc.taskCtx.TaskID)
if err != nil {
return nil, fmt.Errorf("failed to get task planned subtasks: %w", err)
}
// after
subtasks, err := stc.taskCtx.DB.GetTaskPlannedSubtasks(ctx, stc.taskCtx.TaskID)
if err != nil {
if errors.Is(err, context.Canceled) {
return nil, err
}
return nil, fmt.Errorf("failed to get task planned subtasks: %w", err)
} Defensive patterns
Strategy: retry
Validate before calling
select { case <-ctx.Done(): return ctx.Err(); default: } Try / catch
subtasks, err := stc.taskCtx.DB.GetTaskPlannedSubtasks(ctx, taskID)
if err != nil {
if errors.Is(err, context.Canceled) { return nil, err }
return nil, fmt.Errorf("failed to get task planned subtasks: %w", err)
} Prevention
- Size the DB pool for the number of concurrent workers
- Handle graceful shutdown by cancelling worker loops before DB teardown
- Add retry with backoff around PopSubtask in worker loops
When it happens
Trigger: Calling PopSubtask when the DB is unreachable, the query context is cancelled by flow shutdown, or the planned-subtasks query fails to scan rows.
Common situations: Postgres restart while workers are polling for work; flow context cancelled during graceful shutdown so ctx.Err() surfaces as the wrapped error; pool exhaustion with many concurrent flows.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- token not found in database
- failed to create flow in DB: %w
- failed to get user %d: %w
- failed to get flow primary container: %w
- failed to set flow %d status: %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/e53b18d2fa7accac.
Report an issue: GitHub.