vxcontrol/pentagi · warning

operation %d: modify operation missing both title and descri

Error message

operation %d: modify operation missing both title and description fields

What it means

A modify operation with an ID that is empty on both editable fields (title and description) is rejected: it would be a no-op or an accidental wipe. applySubtaskOperations requires at least one non-empty field to know what to change.

Source

Thrown at backend/pkg/providers/subtask_patch.go:78

				opLogger.Error(err.Error())
				return nil, err
			}
			if _, ok := idToIdx[*op.ID]; !ok {
				err := fmt.Errorf("operation %d: subtask with id %d not found for removal", i, *op.ID)
				opLogger.Error(err.Error())
				return nil, err
			}
			removed[*op.ID] = true
			opLogger.WithField("subtask_id", *op.ID).Debug("marked subtask for removal")

		case tools.SubtaskOpModify:
			if op.ID == nil {
				err := fmt.Errorf("operation %d: modify operation missing required id field", i)
				opLogger.Error(err.Error())
				return nil, err
			}
			if op.Title == "" && op.Description == "" {
				err := fmt.Errorf("operation %d: modify operation missing both title and description fields", i)
				opLogger.Error(err.Error())
				return nil, err
			}
			idx, ok := idToIdx[*op.ID]
			if !ok {
				err := fmt.Errorf("operation %d: subtask with id %d not found for modification", i, *op.ID)
				opLogger.Error(err.Error())
				return nil, err
			}
			// Only update fields that are provided
			if op.Title != "" {
				result[idx].Title = op.Title
				opLogger.WithField("new_title", op.Title).Debug("updated subtask title")
			}
			if op.Description != "" {
				result[idx].Description = op.Description
				opLogger.WithField("new_description_len", len(op.Description)).Debug("updated subtask description")
			}

View on GitHub (pinned to ea665308ba)

Solutions

  1. Retry the refiner call and instruct the model to only emit modify ops that change something.
  2. Filter out empty modify operations client-side before applying the patch.
  3. Add prompt guidance: omit modify operations that make no changes.
  4. Treat this as a no-op and skip the operation if you control the caller.

Example fix

// before
{"op":"modify","id":2,"title":"","description":""} // no change
// after: either drop the op or provide real content
{"op":"modify","id":2,"description":"Enumerate subdomains with amass"}
Defensive patterns

Strategy: validation

Validate before calling

for i, op := range ops {
    if op.Op == tools.SubtaskOpModify && op.Title == "" && op.Description == "" {
        return fmt.Errorf("op %d: modify is a no-op", i)
    }
}

Type guard

func modifiesSomething(op tools.SubtaskOperation) bool {
    return op.Title != "" || op.Description != ""
}

Try / catch

patched, err := applySubtaskOperations(ctx, logger, ops, subtasks)
if err != nil && strings.Contains(err.Error(), "missing both title and description") {
    // drop no-op modify ops and reapply the rest
    ops = filterNoopModifies(ops)
    patched, err = applySubtaskOperations(ctx, logger, ops, subtasks)
}

Prevention

When it happens

Trigger: LLM emits {"op":"modify","id":2} (or with "title":"","description":"") — the patch carries no actual change, so validation fails.

Common situations: Model echoing back a subtask unchanged; prompt asking for 'review and update' causing empty updates; template/serialization dropping optional empty strings leaving a bare modify.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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