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

  1. Check the wrapped cause — connection errors warrant DB restart/reconnect handling
  2. Distinguish context.Canceled from real DB errors and treat cancellation as benign
  3. Ensure connection pool size matches number of concurrent flow workers
  4. 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

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


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/e53b18d2fa7accac. Report an issue: GitHub.