vxcontrol/pentagi · error

operation %d: modify requires at least title or description

Error message

operation %d: modify requires at least title or description

What it means

For SubtaskOpModify, Validate requires at least one of Title or Description to be non-empty (a modify that changes nothing is rejected). This error fires when an ID is supplied but both fields are empty.

Source

Thrown at backend/pkg/tools/args.go:337

	for i, op := range sp.Operations {
		switch op.Op {
		case SubtaskOpAdd:
			if op.Title == "" {
				return fmt.Errorf("operation %d: add requires title", i)
			}
			if op.Description == "" {
				return fmt.Errorf("operation %d: add requires description", i)
			}
		case SubtaskOpRemove:
			if op.ID == nil {
				return fmt.Errorf("operation %d: remove requires id", i)
			}
		case SubtaskOpModify:
			if op.ID == nil {
				return fmt.Errorf("operation %d: modify requires id", i)
			}
			if op.Title == "" && op.Description == "" {
				return fmt.Errorf("operation %d: modify requires at least title or description", i)
			}
		case SubtaskOpReorder:
			if op.ID == nil {
				return fmt.Errorf("operation %d: reorder requires id", i)
			}
		default:
			return fmt.Errorf("operation %d: unknown operation type %q", i, op.Op)
		}
	}
	return nil
}

type Bool bool

func (b *Bool) UnmarshalJSON(data []byte) error {
	sdata := strings.Trim(strings.ToLower(string(data)), "' \"\n\r\t")
	switch sdata {
	case "true":

View on GitHub (pinned to ea665308ba)

Solutions

  1. Provide the new title or description the modify should apply.
  2. Drop no-op modify operations from the patch before validation.
  3. Use remove+add instead if the intent was to replace a subtask entirely.

Example fix

// before
ops := []SubtaskOperation{{Op: SubtaskOpModify, ID: int64Ptr(7)}}
// after
ops := []SubtaskOperation{{Op: SubtaskOpModify, ID: int64Ptr(7), Description: "Escalate privileges after initial access"}}
Defensive patterns

Strategy: validation

Validate before calling

for i, op := range ops {
    if op.Op == "modify" && op.Title == "" && op.Description == "" {
        return fmt.Errorf("op %d: modify needs title or description", i)
    }
}

Type guard

func isMeaningfulModify(op SubtaskOperation) bool {
    return op.Op != SubtaskOpModify || op.Title != "" || op.Description != ""
}

Try / catch

if err := patch.Validate(); err != nil {
    if strings.Contains(err.Error(), "modify requires at least title or description") {
        // drop the no-op operation or fill in the intended change
    }
}

Prevention

When it happens

Trigger: Patch operation {"op":"modify","id":7} with empty/omitted title and description, via patch_flow_subtasks or SubtaskPatch.Validate.

Common situations: LLM emits no-op modify entries; code that copies an operation struct and blanks both fields; attempting to 'touch' a subtask to trigger refresh.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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