vxcontrol/pentagi · error · stateGuard

task %d has a subtask (ID: %d, %q) currently running. Call %

Error message

task %d has a subtask (ID: %d, %q) currently running. Call %s first, then retry

What it means

A stateGuard error raised by the create/patch-subtasks tool when the task has a subtask currently in SubtaskStatusRunning. Patching the plan while a subtask is executing is disallowed because it would race with live execution; the agent must first stop the flow via the stop_flow tool, then retry. This is an intentional concurrency guard, not a system failure.

Source

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

	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",
					action.TaskID, st.ID, st.Title, SubmitFlowInputToolName))
			case database.SubtaskStatusRunning:
				return "", stateGuard(fmt.Errorf(
					"task %d has a subtask (ID: %d, %q) currently running. "+
						"Call %s first, then retry",
					action.TaskID, st.ID, st.Title, StopFlowToolName))
			}
		}

		return "", stateGuard(fmt.Errorf(
			"no 'created' subtasks found for task %d; "+
				"all subtasks have been executed or the task has no plan yet. "+
				"Use %s to create a new task instead",
			action.TaskID, SubmitFlowInputToolName))
	}

	patch := SubtaskPatch{
		Operations: action.Operations,
		Message:    action.Message,
	}

View on GitHub (pinned to ea665308ba)

Solutions

  1. Call stop_flow to stop the running subtask, then retry the patch operation
  2. Wait until the running subtask completes, then patch the task's plan
  3. If a subtask is stuck in 'running' after a crash, restart the flow/worker so its status is reconciled, then retry

Example fix

// before
// patch-subtasks(task_id=42, operations=[...]) -> error: subtask 17 running
// after
// 1) stop_flow(subtask_id=17)
// 2) patch-subtasks(task_id=42, operations=[...])
Defensive patterns

Strategy: validation

Validate before calling

// before patching, verify no subtask of the task is running
for _, st := range subtasks {
	if st.TaskID == taskID && st.Status == database.SubtaskStatusRunning {
		return fmt.Errorf("subtask %d is running; call stop_flow first", st.ID)
	}
}

Try / catch

out, err := mgr.Handle(ctx, action)
if err != nil {
	if strings.Contains(err.Error(), "currently running") {
		// call stop_flow for the running subtask, then retry the patch
	}
	return err
}

Prevention

When it happens

Trigger: Calling patch-subtasks (or create-subtasks with operations) for a task that has a subtask whose status is 'running'.

Common situations: The agent tries to revise a plan while a long-running subtask (e.g. an nmap scan) is still executing; a stale or crashed run left a subtask stuck in 'running' status; two agents operate on the same flow concurrently.

Related errors


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