vxcontrol/pentagi · error

failed to get planned subtasks for task %d: %w

Error message

failed to get planned subtasks for task %d: %w

What it means

This error wraps a database failure from GetTaskPlannedSubtasks while the flow tool Handle is processing a create-subtasks/patch-subtasks action. It means the backend could not read the planned subtasks for the given task ID from PostgreSQL; the underlying DB error is preserved via %w. It is thrown before any subtask state checks can run.

Source

Thrown at backend/pkg/tools/flow_manager.go:879

	}

	taskBelongsToFlow := false
	for _, task := range tasks {
		if task.ID == action.TaskID {
			taskBelongsToFlow = true
			break
		}
	}
	if !taskBelongsToFlow {
		return "", stateGuard(fmt.Errorf(
			"task ID %d was not found in this flow; "+
				"obtain a valid task ID from %s with detail='tasks'",
			action.TaskID, GetFlowStatusToolName))
	}

	planned, err := t.db.GetTaskPlannedSubtasks(ctx, action.TaskID)
	if err != nil {
		return "", fmt.Errorf("failed to get planned subtasks for task %d: %w", action.TaskID, err)
	}

	if len(planned) == 0 && len(action.Operations) > 0 {
		subtasks, err := t.db.GetFlowSubtasks(ctx, t.flowID)
		if err != nil {
			return "", fmt.Errorf("failed to check subtask state for task %d: %w", action.TaskID, err)
		}

		for _, st := range subtasks {
			if st.TaskID != action.TaskID {
				continue
			}
			switch st.Status {
			case database.SubtaskStatusWaiting:
				return "", stateGuard(fmt.Errorf(
					"task %d has a subtask (ID: %d, %q) waiting for user input. "+
						"Only 'created' subtasks can be patched, but you can include the waiting subtask's ID in your operations to modify or remove it. "+
						"Alternatively, answer it via %s first",

View on GitHub (pinned to ea665308ba)

Solutions

  1. Inspect the wrapped cause (%w) in the logs to identify the underlying DB error
  2. Check PostgreSQL connectivity/health and connection-pool settings
  3. Retry the tool action; transient DB failures usually resolve on reconnect
  4. If persistent, verify migrations ran and the tasks/subtasks tables exist

Example fix

// before
planned, err := t.db.GetTaskPlannedSubtasks(ctx, action.TaskID)
if err != nil {
	return "", fmt.Errorf("failed to get planned subtasks for task %d: %w", action.TaskID, err)
}
// after
planned, err := t.db.GetTaskPlannedSubtasks(ctx, action.TaskID)
if err != nil {
	logger.Warn(ctx, "retrying planned-subtask fetch", slog.Int("task_id", action.TaskID), slog.String("err", err.Error()))
	planned, err = t.db.GetTaskPlannedSubtasks(ctx, action.TaskID)
	if err != nil {
		return "", fmt.Errorf("failed to get planned subtasks for task %d: %w", action.TaskID, err)
	}
}
Defensive patterns

Strategy: retry

Validate before calling

// caller-side preflight
if taskID <= 0 {
	return fmt.Errorf("invalid task ID %d", taskID)
}
if err := ctx.Err(); err != nil {
	return fmt.Errorf("context already cancelled: %w", err)
}

Try / catch

// in Go, inspect the wrapped error
planned, err := mgr.Handle(ctx, action)
if err != nil {
	var dbErr *pgconn.ConnectError
	if errors.As(err, &dbErr) || errors.Is(err, context.DeadlineExceeded) {
		// transient: retry with backoff
	}
	return fmt.Errorf("get planned subtasks: %w", err)
}

Prevention

When it happens

Trigger: Any call to the create_subtasks (or patch) tool action where t.db.GetTaskPlannedSubtasks(ctx, action.TaskID) returns a non-nil error — e.g. DB connection dropped, query timeout, or the task row lock is unavailable.

Common situations: PostgreSQL outage or connection pool exhaustion under load; context deadline exceeded because the agent's request timed out; transient network blip between the backend and the database; corrupted schema after a failed migration.

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/3561fe4cddee593a. Report an issue: GitHub.