vxcontrol/pentagi · error

failed to get flow subtasks: %w

Error message

failed to get flow subtasks: %w

What it means

This error is thrown by the get_flow_status tool's buildSummary (backend/pkg/tools/flow_manager.go:99) when the database query GetFlowSubtasks fails while assembling the flow summary. It wraps the underlying DB error with %w so the root cause (connection failure, timeout, SQL error) is preserved. It means the tool could not read the subtask list for the tool's flowID.

Source

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

		return t.buildSubtasksList(ctx, action.TaskID.PtrInt64(), verbose)
	case FlowStatusDetailRunning:
		return t.buildRunningInfo(ctx, verbose)
	case FlowStatusDetailPlanned:
		return t.buildPlannedList(ctx, action.TaskID.PtrInt64(), verbose)
	default:
		return "", fmt.Errorf("unknown detail level %q; use one of: summary, tasks, subtasks, running, planned", action.Detail)
	}
}

func (t *flowStatusTool) buildSummary(ctx context.Context, verbose bool) (string, error) {
	tasks, err := t.db.GetFlowTasks(ctx, t.flowID)
	if err != nil {
		return "", fmt.Errorf("failed to get flow tasks: %w", err)
	}

	subtasks, err := t.db.GetFlowSubtasks(ctx, t.flowID)
	if err != nil {
		return "", fmt.Errorf("failed to get flow subtasks: %w", err)
	}

	taskCounts := map[string]int{"created": 0, "running": 0, "waiting": 0, "finished": 0, "failed": 0}
	var activeTask *database.Task
	for i, task := range tasks {
		taskCounts[string(task.Status)]++
		if task.Status == database.TaskStatusRunning || task.Status == database.TaskStatusWaiting {
			activeTask = &tasks[i]
		}
	}

	stCounts := map[string]int{"created": 0, "running": 0, "waiting": 0, "finished": 0, "failed": 0}
	var activeST *database.Subtask
	for i, st := range subtasks {
		stCounts[string(st.Status)]++
		if st.Status == database.SubtaskStatusRunning || st.Status == database.SubtaskStatusWaiting {
			activeST = &subtasks[i]
		}

View on GitHub (pinned to ea665308ba)

Solutions

  1. Check PostgreSQL connectivity and container health (docker compose ps, pg_isready) and restart the database if it is down.
  2. Inspect the wrapped cause with errors.Unwrap / logs — fix the specific DB error (timeout, pool limits, bad credentials in .env).
  3. Verify goose migrations ran to completion (backend/migrations/sql) so the subtasks table/schema matches the SQLC queries.
  4. Increase DB pool size / statement timeout, or retry the tool call once the database is reachable.

Example fix

// before
subtasks, err := t.db.GetFlowSubtasks(ctx, t.flowID)
if err != nil {
	return "", fmt.Errorf("failed to get flow subtasks: %w", err)
}
// after: retry transient DB failures once before failing the tool call
subtasks, err := t.db.GetFlowSubtasks(ctx, t.flowID)
if err != nil && isTransientDBError(err) {
	time.Sleep(500 * time.Millisecond)
	subtasks, err = t.db.GetFlowSubtasks(ctx, t.flowID)
}
if err != nil {
	return "", fmt.Errorf("failed to get flow subtasks: %w", err)
}
Defensive patterns

Strategy: retry

Validate before calling

// before relying on the tool, confirm DB reachability from the app host
rows, err := db.QueryContext(ctx, "SELECT 1 FROM subtasks LIMIT 1")
if err != nil {
	return fmt.Errorf("database not ready for get_flow_status: %w", err)
}

Try / catch

// Go: classify the wrapped cause before reacting
result, err := tool.Handle(ctx, "get_flow_status", args)
if err != nil {
	if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) {
		return retryWithBackoff(ctx, err)
	}
	var pgErr *pgconn.PgError
	if errors.As(err, &pgErr) && pgErr.Code == "53300" { // too_many_connections
		return backoffAndRetry(ctx)
	}
	return fmt.Errorf("get_flow_status failed: %w", err)
}

Prevention

When it happens

Trigger: Calling the get_flow_status tool with detail='summary' (Handle -> buildSummary) while t.db.GetFlowSubtasks(ctx, t.flowID) returns an error — e.g. PostgreSQL unreachable, statement timeout, context cancellation, or a schema mismatch after a failed migration.

Common situations: Database container down or restarting during heavy agent runs; connection-pool exhaustion under many concurrent flows; pgvector extension or migration version mismatch; context deadline exceeded because the caller's LLM request timeout is shorter than the DB latency.

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/0b2f443d221f8470. Report an issue: GitHub.