{"record":{"id":"054c6620a7bb9783","repo":"vxcontrol/pentagi","slug":"failed-to-check-subtask-state-for-task-d-w","errorCode":null,"errorMessage":"failed to check subtask state for task %d: %w","messagePattern":"failed to check subtask state for task (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/tools/flow_manager.go","lineNumber":885,"sourceCode":"\t\t\tbreak\n\t\t}\n\t}\n\tif !taskBelongsToFlow {\n\t\treturn \"\", stateGuard(fmt.Errorf(\n\t\t\t\"task ID %d was not found in this flow; \"+\n\t\t\t\t\"obtain a valid task ID from %s with detail='tasks'\",\n\t\t\taction.TaskID, GetFlowStatusToolName))\n\t}\n\n\tplanned, err := t.db.GetTaskPlannedSubtasks(ctx, action.TaskID)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to get planned subtasks for task %d: %w\", action.TaskID, err)\n\t}\n\n\tif len(planned) == 0 && len(action.Operations) > 0 {\n\t\tsubtasks, err := t.db.GetFlowSubtasks(ctx, t.flowID)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"failed to check subtask state for task %d: %w\", action.TaskID, err)\n\t\t}\n\n\t\tfor _, st := range subtasks {\n\t\t\tif st.TaskID != action.TaskID {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tswitch st.Status {\n\t\t\tcase database.SubtaskStatusWaiting:\n\t\t\t\treturn \"\", stateGuard(fmt.Errorf(\n\t\t\t\t\t\"task %d has a subtask (ID: %d, %q) waiting for user input. \"+\n\t\t\t\t\t\t\"Only 'created' subtasks can be patched, but you can include the waiting subtask's ID in your operations to modify or remove it. \"+\n\t\t\t\t\t\t\"Alternatively, answer it via %s first\",\n\t\t\t\t\taction.TaskID, st.ID, st.Title, SubmitFlowInputToolName))\n\t\t\tcase database.SubtaskStatusRunning:\n\t\t\t\treturn \"\", stateGuard(fmt.Errorf(\n\t\t\t\t\t\"task %d has a subtask (ID: %d, %q) currently running. \"+\n\t\t\t\t\t\t\"Call %s first, then retry\",\n\t\t\t\t\taction.TaskID, st.ID, st.Title, StopFlowToolName))","sourceCodeStart":867,"sourceCodeEnd":903,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/tools/flow_manager.go#L867-L903","documentation":"This error wraps a failure of t.db.GetFlowSubtasks for the flow while Handle was checking whether any existing subtasks belong to the task, because no planned subtasks were found but the action carried operations. It is a defensive consistency check: the agent wants to patch/create subtasks but the DB state could not be verified. The wrapped cause carries the real DB error.","triggerScenarios":"Create/patch-subtasks action with len(action.Operations) > 0 and zero planned subtasks, and GetFlowSubtasks(ctx, t.flowID) returns a DB error (connection failure, timeout, cancelled context).","commonSituations":"Database under heavy load during large flows; ctx cancelled by an upstream deadline; replica/failover hiccup in PostgreSQL; misconfigured DSN after an environment change.","solutions":["Check the wrapped DB error in logs to find the root cause","Verify PostgreSQL is reachable and the connection pool is not exhausted","Retry the action once connectivity is restored","Ensure goose migrations completed so the subtasks table is queryable"],"exampleFix":"// before\nsubtasks, err := t.db.GetFlowSubtasks(ctx, t.flowID)\nif err != nil {\n\treturn \"\", fmt.Errorf(\"failed to check subtask state for task %d: %w\", action.TaskID, err)\n}\n// after\nsubtasks, err := t.db.GetFlowSubtasks(ctx, t.flowID)\nif err != nil {\n\tif ctx.Err() != nil {\n\t\treturn \"\", fmt.Errorf(\"flow context cancelled while checking subtask state for task %d: %w\", action.TaskID, ctx.Err())\n\t}\n\treturn \"\", fmt.Errorf(\"failed to check subtask state for task %d: %w\", action.TaskID, err)\n}","handlingStrategy":"retry","validationCode":"// preflight: ensure flow context and DB are alive before invoking the tool\nif err := db.PingContext(ctx); err != nil {\n\treturn fmt.Errorf(\"database unreachable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"subtasks, err := mgr.Handle(ctx, action)\nif err != nil && strings.Contains(err.Error(), \"failed to check subtask state\") {\n\tif errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {\n\t\t// re-invoke with a fresh context\n\t}\n}","preventionTips":["Avoid invoking plan-mutation tools with a nearly expired context/deadline","Ensure the subtasks table exists (migrations ran) before running flows","Retry transient DB errors instead of abandoning the flow action","Watch DB connection-pool metrics during large flows"],"tags":["database","flow-manager","db-query"],"backgroundTag":"database-query-failed","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}