vxcontrol/pentagi · error · stateGuard

task ID %d was not found in this flow; obtain a valid task I

Error message

task ID %d was not found in this flow; obtain a valid task ID from %s with detail='tasks'

What it means

The task_id passed to patch_flow_subtasks parses and is positive, but no task with that ID exists in this flow — GetFlowTasks found no matching ID, so the patch is rejected with a state guard. This prevents cross-flow or stale ID patching.

Source

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

	for _, task := range tasks {
		if task.Status == database.TaskStatusRunning {
			return "", stateGuard(fmt.Errorf(
				"task %q (ID: %d) is currently running; "+
					"patching is not allowed while a task is executing. "+
					"Call %s first, then retry %s",
				task.Title, task.ID, StopFlowToolName, PatchFlowSubtasksToolName))
		}
	}

	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 {

View on GitHub (pinned to ea665308ba)

Solutions

  1. Call get_flow_status with detail='tasks' to list the actual task IDs in this flow.
  2. Resend patch_flow_subtasks using a valid ID from that list.
  3. If the flow was restarted, re-fetch IDs — old ones are no longer valid.
  4. Verify you are operating on the intended flow, not a different one.

Example fix

// before: guessing an ID
{"task_id": 999, "operations": [...]}
// after: use get_flow_status detail='tasks' to find the real ID, then
{"task_id": 3, "operations": [...]}
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the task ID belongs to the current flow
validIDs := map[int64]bool{}
for _, t := range getFlowStatusTasks(ctx) { validIDs[t.ID] = true }
if !validIDs[taskID] {
    return fmt.Errorf("task %d is not in this flow; refetch IDs via get_flow_status", taskID)
}

Type guard

func taskBelongsToFlow(taskID int64, tasks []Task) bool {
    for _, t := range tasks {
        if t.ID == taskID { return true }
    }
    return false
}

Try / catch

_, err := tool.Handle(ctx, "patch_flow_subtasks", args)
if err != nil && strings.Contains(err.Error(), "was not found in this flow") {
    ids := fetchTaskIDs(ctx) // get_flow_status detail='tasks'
    args = rebuildArgsWithValidID(ids)
    _, _ = tool.Handle(ctx, "patch_flow_subtasks", args)
}

Prevention

When it happens

Trigger: Calling patch_flow_subtasks with a task ID from a different flow, an ID fabricated/hallucinated by the LLM, or an ID from a task that was deleted when the flow was restarted.

Common situations: LLM inventing plausible-looking IDs instead of calling get_flow_status; caching task IDs across flow restarts; copy-pasting IDs between flows or sessions.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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