{"record":{"id":"4d538fb374b8e48a","repo":"vxcontrol/pentagi","slug":"operation-d-add-requires-title","errorCode":null,"errorMessage":"operation %d: add requires title","messagePattern":"operation (.+?): add requires title","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/tools/args.go","lineNumber":323,"sourceCode":"type WaitFlowCompletionAction struct {\n\tTimeout Int64  `json:\"timeout\" jsonschema:\"required,type=integer\" jsonschema_description:\"How long to wait for the running automation task to finish, in seconds. Use 0 or a negative value to apply the default timeout of 60 seconds. Values above 3600 are capped at 3600 seconds (1 hour).\"`\n\tMessage string `json:\"message\" jsonschema:\"required,title=Wait message\" jsonschema_description:\"Engagement-log entry — a 1-2 short sentence running commentary explaining why you are waiting for the automation to finish. Written in the engagement language declared by your system prompt.\"`\n}\n\n// PatchFlowSubtasksAction defines arguments for the patch_flow_subtasks tool.\ntype PatchFlowSubtasksAction struct {\n\tTaskID     int64              `json:\"task_id\" jsonschema:\"required,type=integer\" jsonschema_description:\"ID of the task whose subtask plan to modify. Obtain this from get_flow_status with detail='tasks'.\"`\n\tOperations []SubtaskOperation `json:\"operations\" jsonschema:\"required\" jsonschema_description:\"Delta operations to apply: add (insert new subtask at a position), remove (delete by ID), modify (update title/description), reorder (move to different position). Empty array returns the current plan unchanged. Each operation's title/description, when present, is an engagement-log plan entry (see operations).\"`\n\tMessage    string             `json:\"message\" jsonschema:\"required,title=Patch summary\" jsonschema_description:\"Engagement-log entry — a 1-2 short sentence running commentary describing what changes are being made to the plan. Written in the engagement language declared by your system prompt.\"`\n}\n\n// ValidateSubtaskPatch validates the operations in a SubtaskPatch\nfunc (sp SubtaskPatch) Validate() error {\n\tfor i, op := range sp.Operations {\n\t\tswitch op.Op {\n\t\tcase SubtaskOpAdd:\n\t\t\tif op.Title == \"\" {\n\t\t\t\treturn fmt.Errorf(\"operation %d: add requires title\", i)\n\t\t\t}\n\t\t\tif op.Description == \"\" {\n\t\t\t\treturn fmt.Errorf(\"operation %d: add requires description\", i)\n\t\t\t}\n\t\tcase SubtaskOpRemove:\n\t\t\tif op.ID == nil {\n\t\t\t\treturn fmt.Errorf(\"operation %d: remove requires id\", i)\n\t\t\t}\n\t\tcase SubtaskOpModify:\n\t\t\tif op.ID == nil {\n\t\t\t\treturn fmt.Errorf(\"operation %d: modify requires id\", i)\n\t\t\t}\n\t\t\tif op.Title == \"\" && op.Description == \"\" {\n\t\t\t\treturn fmt.Errorf(\"operation %d: modify requires at least title or description\", i)\n\t\t\t}\n\t\tcase SubtaskOpReorder:\n\t\t\tif op.ID == nil {\n\t\t\t\treturn fmt.Errorf(\"operation %d: reorder requires id\", i)","sourceCodeStart":305,"sourceCodeEnd":341,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/tools/args.go#L305-L341","documentation":"SubtaskPatch.Validate checks each SubtaskOperation in the patch. For op == SubtaskOpAdd, both Title and Description are mandatory; this error fires when Title is empty. It protects the task planner from creating unnamed subtasks via the patch_flow_subtasks tool.","triggerScenarios":"Submitting PatchFlowSubtasksAction with an operations entry {\"op\":\"add\"} (or op=add via SubtaskPatch) whose title field is empty or omitted; LLM tool call omitting title in an add operation.","commonSituations":"LLM agents generate add operations with only a description; JSON marshaling drops an empty title field; hand-written automation scripts building patches.","solutions":["Set a non-empty title on every add operation before calling Validate/applying the patch.","Pre-validate the operations array client-side and reject add ops missing title or description.","Tighten the tool's JSON schema description/prompt so the LLM always supplies both fields."],"exampleFix":"// before\nops := []SubtaskOperation{{Op: SubtaskOpAdd, Description: \"scan ports\"}}\n// after\nops := []SubtaskOperation{{Op: SubtaskOpAdd, Title: \"Port scan\", Description: \"scan ports\"}}","handlingStrategy":"validation","validationCode":"for i, op := range ops {\n    if op.Op == \"add\" && (op.Title == \"\" || op.Description == \"\") {\n        return fmt.Errorf(\"op %d: add needs title and description\", i)\n    }\n}","typeGuard":"func validAddOp(op SubtaskOperation) bool {\n    return op.Op == SubtaskOpAdd && op.Title != \"\" && op.Description != \"\"\n}","tryCatchPattern":"if err := patch.Validate(); err != nil {\n    var idx int\n    if _, scanErr := fmt.Sscanf(err.Error(), \"operation %d:\", &idx); scanErr == nil {\n        // repair or drop operations[idx] and revalidate\n    }\n}","preventionTips":["Always emit both title and description for add operations in LLM tool prompts.","Pre-validate patches client-side before invoking patch_flow_subtasks.","Set jsonschema required fields so the model is constrained at generation time.","Drop malformed add ops instead of failing the whole patch when partial application is acceptable."],"tags":["validation","tool-args","subtasks"],"backgroundTag":"missing-required-argument","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}