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
- Check PostgreSQL connectivity and container health (docker compose ps, pg_isready) and restart the database if it is down.
- Inspect the wrapped cause with errors.Unwrap / logs — fix the specific DB error (timeout, pool limits, bad credentials in .env).
- Verify goose migrations ran to completion (backend/migrations/sql) so the subtasks table/schema matches the SQLC queries.
- 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
- Monitor PostgreSQL health (pg_isready probe, container restart policy) before agent runs.
- Size the connection pool for concurrent flow goroutines and set sane statement timeouts.
- Keep goose migrations applied on every deploy so schema matches SQLC queries.
- Alert on wrapped DB errors from tool handlers rather than retrying blindly.
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
- failed to get subtasks: %w
- failed to get subtask msg logs: %w
- failed to check flow status: %w
- failed to set flow %d status: %w
- failed to renew flow %d status: %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/0b2f443d221f8470.
Report an issue: GitHub.