{"record":{"id":"41e9ac53742a6968","repo":"vxcontrol/pentagi","slug":"failed-to-parse-patch-flow-subtasks-args-w","errorCode":null,"errorMessage":"failed to parse patch_flow_subtasks args: %w","messagePattern":"failed to parse patch_flow_subtasks args: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/tools/flow_manager.go","lineNumber":840,"sourceCode":"// patchFlowSubtasksTool implements patch_flow_subtasks.\ntype patchFlowSubtasksTool struct {\n\tflowID  int64\n\tdb      database.Querier\n\thandler func(ctx context.Context, taskID int64, patch SubtaskPatch) error\n}\n\nfunc NewPatchFlowSubtasksTool(\n\tflowID int64,\n\tdb database.Querier,\n\thandler func(ctx context.Context, taskID int64, patch SubtaskPatch) error,\n) *patchFlowSubtasksTool {\n\treturn &patchFlowSubtasksTool{flowID: flowID, db: db, handler: handler}\n}\n\nfunc (t *patchFlowSubtasksTool) Handle(ctx context.Context, name string, args json.RawMessage) (string, error) {\n\tvar action PatchFlowSubtasksAction\n\tif err := json.Unmarshal(args, &action); err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to parse patch_flow_subtasks args: %w\", err)\n\t}\n\n\tif action.TaskID <= 0 {\n\t\treturn \"\", fmt.Errorf(\"task_id must be a positive integer\")\n\t}\n\n\t// Validate flow is not running\n\ttasks, err := t.db.GetFlowTasks(ctx, t.flowID)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to check flow status: %w\", err)\n\t}\n\n\tfor _, task := range tasks {\n\t\tif task.Status == database.TaskStatusRunning {\n\t\t\treturn \"\", stateGuard(fmt.Errorf(\n\t\t\t\t\"task %q (ID: %d) is currently running; \"+\n\t\t\t\t\t\"patching is not allowed while a task is executing. \"+\n\t\t\t\t\t\"Call %s first, then retry %s\",","sourceCodeStart":822,"sourceCodeEnd":858,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/tools/flow_manager.go#L822-L858","documentation":"patch_flow_subtasks received arguments that could not be unmarshalled into PatchFlowSubtasksAction, so the tool rejects the call before touching the database. The JSON structure/types of the arguments do not match the action schema (e.g. task_id is a string, operations is not an array, malformed JSON).","triggerScenarios":"The LLM or caller emits patch_flow_subtasks args with invalid JSON or wrong field types: task_id as a string instead of number, missing required shape of operations, trailing garbage, or double-encoded JSON strings.","commonSituations":"LLM hallucinating a different schema for the tool; hand-crafted API calls with wrong payload shape; older prompt/tool definitions after a schema change; JSON strings quoted one level too many.","solutions":["Read the wrapped error (%w) to see the exact unmarshal failure (field and type).","Resend with valid JSON: {\"task_id\": <int>, \"operations\": [...]}.","Ensure task_id is a JSON number, not a quoted string.","If an LLM produced the args, regenerate with the current tool schema; update stale prompt definitions."],"exampleFix":"// before\n{\"task_id\": \"42\", \"operations\": [{\"op\": \"remove\", \"index\": 0}]}\n// after\n{\"task_id\": 42, \"operations\": [{\"op\": \"remove\", \"index\": 0}]}","handlingStrategy":"validation","validationCode":"// Validate the payload shape before invoking the tool\nraw, _ := json.Marshal(args)\nvar probe struct {\n    TaskID     *int64           `json:\"task_id\"`\n    Operations []map[string]any `json:\"operations\"`\n}\nif err := json.Unmarshal(raw, &probe); err != nil || probe.TaskID == nil {\n    return errors.New(\"invalid patch_flow_subtasks args: task_id must be a JSON number\")\n}","typeGuard":"func validPatchArgs(args json.RawMessage) bool {\n    var a struct {\n        TaskID     int64   `json:\"task_id\"`\n        Operations []any   `json:\"operations\"`\n    }\n    return json.Unmarshal(args, &a) == nil && a.TaskID > 0 && a.Operations != nil\n}","tryCatchPattern":"if _, err := tool.Handle(ctx, \"patch_flow_subtasks\", args); err != nil {\n    var uErr *json.UnmarshalTypeError\n    if errors.As(err, &uErr) {\n        log.Printf(\"bad args field %s: expected %s\", uErr.Field, uErr.Type)\n    }\n}","preventionTips":["Schema-validate LLM-generated tool arguments before dispatch.","Keep task_id as a JSON number, never a quoted string.","Regenerate tool schemas in prompts after any action struct change.","Unit-test the exact JSON payloads your client sends."],"tags":["json","validation","tool-arguments"],"backgroundTag":"json-unmarshal-error","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}