vxcontrol/pentagi · error
failed to patch subtasks for task %d: %w
Error message
failed to patch subtasks for task %d: %w
What it means
After the patch passes local validation, the handler calls t.handler (the flow manager's DB-backed patch function) to apply the operations to the task's planned subtasks. If persistence fails — unknown task ID, referenced subtask ID does not exist, or a database error — the error is wrapped as "failed to patch subtasks for task %d: %w". No partial application is reported as success; either the whole patch applies or this error is returned.
Source
Thrown at backend/pkg/tools/flow_manager.go:928
"Use %s to create a new task instead",
action.TaskID, SubmitFlowInputToolName))
}
patch := SubtaskPatch{
Operations: action.Operations,
Message: action.Message,
}
if err := patch.Validate(); err != nil {
return "", fmt.Errorf("invalid subtask patch: %w", err)
}
if len(action.Operations) == 0 {
return fmt.Sprintf("No operations provided — the subtask plan for task %d is unchanged.", action.TaskID), nil
}
if err := t.handler(ctx, action.TaskID, patch); err != nil {
return "", fmt.Errorf("failed to patch subtasks for task %d: %w", action.TaskID, err)
}
// Query the new subtask list so the LLM can correlate the patched entries with their new IDs.
newPlanned, err := t.db.GetTaskPlannedSubtasks(ctx, action.TaskID)
if err != nil {
// Not fatal — operations were applied; just warn and skip the list.
return fmt.Sprintf(
"%d operation(s) applied to the subtask plan for task %d. "+
"Could not retrieve updated subtask list: %s. "+
"Call %s with detail='planned' and task_id=%d to verify.",
len(action.Operations), action.TaskID, err,
GetFlowStatusToolName, action.TaskID), nil
}
sb := &strings.Builder{}
fmt.Fprintf(sb,
"%d operation(s) applied to the subtask plan for task %d. "+
"Updated planned subtasks (new IDs assigned after recreation):\n",View on GitHub (pinned to ea665308ba)
Solutions
- Re-fetch the current plan with get_flow_status (detail=planned or subtasks) and retry the patch using fresh task/subtask ids.
- Verify task_id was copied from get_flow_status detail=tasks output, not invented or taken from a different flow.
- Split large patches into smaller ones so a remove followed by a modify of the same id is not attempted in one atomic batch.
- If the wrapped cause is a DB/connection error, retry after the database recovers; check backend logs and PostgreSQL health.
Example fix
// before: patching with a stale id
{"task_id": 3, "operations": [{"op": "modify", "id": 17, "title": "Updated"}]}
// after: re-read plan, then patch with a live id
// GET get_flow_status detail=subtasks -> id 23
{"task_id": 3, "operations": [{"op": "modify", "id": 23, "title": "Updated"}]} Defensive patterns
Strategy: retry
Validate before calling
// Before patching, confirm ids are current:
status, _ := getFlowStatus(ctx, detail="subtasks", taskID=taskID)
liveIDs := map[int64]bool{}
for _, s := range status.Subtasks { liveIDs[s.ID] = true }
for _, op := range operations {
if op.ID != nil && !liveIDs[*op.ID] {
return fmt.Errorf("subtask id %d no longer exists; re-read plan", *op.ID)
}
} Try / catch
if _, err := toolHandle(ctx, action); err != nil {
if strings.HasPrefix(err.Error(), fmt.Sprintf("failed to patch subtasks for task %d:", taskID)) {
// refresh plan via get_flow_status, rebuild operations with live ids, retry once
// if the cause is a DB error, back off and retry after the database recovers
}
} Prevention
- Always fetch task_id and subtask ids from get_flow_status immediately before patching.
- Apply remove-then-modify sequences as separate patch calls, not one batch referencing a just-removed id.
- Monitor PostgreSQL health; transient connection errors surface here wrapped.
- Keep patches small and idempotent so a failed batch can be safely retried.
When it happens
Trigger: Calling patch_flow_subtasks with a task_id that does not exist (or belongs to another flow); an operation referencing a subtask id that was already removed by an earlier operation in the same patch or by a previous call; the underlying SQL/DB connection failing while updating subtask rows.
Common situations: Stale ids: the agent patches using ids read several turns ago while another patch already removed/reordered them; hallucinated task_id not obtained from get_flow_status; transient Postgres outage or connection pool exhaustion during a long engagement.
Related errors
- failed to set subtask %d result: %w
- 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
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/36927bfa1cdea290.
Report an issue: GitHub.