vxcontrol/pentagi · error
task_id must be a positive integer
Error message
task_id must be a positive integer
What it means
patch_flow_subtasks requires a positive integer task_id; the parsed action had task_id <= 0 (missing or non-positive). This is an argument-validation guard executed after JSON parsing succeeds but before any database access.
Source
Thrown at backend/pkg/tools/flow_manager.go:844
handler func(ctx context.Context, taskID int64, patch SubtaskPatch) error
}
func NewPatchFlowSubtasksTool(
flowID int64,
db database.Querier,
handler func(ctx context.Context, taskID int64, patch SubtaskPatch) error,
) *patchFlowSubtasksTool {
return &patchFlowSubtasksTool{flowID: flowID, db: db, handler: handler}
}
func (t *patchFlowSubtasksTool) Handle(ctx context.Context, name string, args json.RawMessage) (string, error) {
var action PatchFlowSubtasksAction
if err := json.Unmarshal(args, &action); err != nil {
return "", fmt.Errorf("failed to parse patch_flow_subtasks args: %w", err)
}
if action.TaskID <= 0 {
return "", fmt.Errorf("task_id must be a positive integer")
}
// Validate flow is not running
tasks, err := t.db.GetFlowTasks(ctx, t.flowID)
if err != nil {
return "", fmt.Errorf("failed to check flow status: %w", err)
}
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))
}
}
View on GitHub (pinned to ea665308ba)
Solutions
- Call get_flow_status with detail='tasks' to obtain valid task IDs.
- Resend patch_flow_subtasks with the real positive task_id.
- If the LLM keeps guessing, include the task list in its context before the patch call.
Example fix
// before
{"task_id": 0, "operations": [...]}
// after: fetch IDs first, then
{"task_id": 17, "operations": [...]} Defensive patterns
Strategy: validation
Validate before calling
if taskID <= 0 {
return errors.New("refusing to patch: fetch a valid task_id via get_flow_status detail='tasks' first")
} Type guard
func hasValidTaskID(args json.RawMessage) bool {
var a struct { TaskID int64 `json:"task_id"` }
if json.Unmarshal(args, &a) != nil { return false }
return a.TaskID > 0
} Try / catch
if _, err := tool.Handle(ctx, "patch_flow_subtasks", args); err != nil &&
strings.Contains(err.Error(), "task_id must be a positive integer") {
// refresh known task IDs and rebuild args
args = buildArgsFromStatus(getFlowStatus(ctx))
} Prevention
- Always fetch task IDs via get_flow_status before patching.
- Never send placeholder/default zero IDs.
- Include the current task list in the LLM's context when it plans a patch.
- Validate IDs client-side before dispatching the tool call.
When it happens
Trigger: Calling patch_flow_subtasks with task_id omitted (defaults to 0) or explicitly 0/negative — typically when the LLM doesn't know the real task ID and emits a placeholder.
Common situations: LLM guessing a task_id because it never fetched the plan; template calls left with default values; client code passing an unset int64 field.
Understand the failure class
Background: "must be a positive integer", "cannot be empty", "invalid argument": how invalid-argument errors work across open-source libraries — this error's family across 33 libraries.
Related errors
- failed to parse patch_flow_subtasks args: %w
- task ID %d was not found in this flow; obtain a valid task I
- invalid subtask patch: %w
- Internal
- Agentlogs.InvalidRequest
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/eed7678bfdd93e1a.
Report an issue: GitHub.