SigNoz/signoz · warning · errors SigNozError

ErrCodeInvalidPatchObject

ErrCodeInvalidPatchObject

Error message

empty object patch request received, at least one of additions or deletions must be present

What it means

NewPatchableObjects builds object additions/deletions for a patch request; it refuses fully empty patches where both additions and deletions slices are empty, since a no-op patch is almost always a client bug.

Source

Thrown at pkg/types/coretypes/object.go:144

		key := obj.Resource.String()
		if _, ok := grouped[key]; !ok {
			grouped[key] = &ObjectGroup{Resource: obj.Resource, Selectors: make([]Selector, 0)}
			order = append(order, key)
		}
		grouped[key].Selectors = append(grouped[key].Selectors, obj.Selector)
	}

	objectGroups := make([]*ObjectGroup, 0, len(order))
	for _, key := range order {
		objectGroups = append(objectGroups, grouped[key])
	}

	return objectGroups
}

func NewPatchableObjects(additions []*ObjectGroup, deletions []*ObjectGroup, verb Verb) ([]*Object, []*Object, error) {
	if len(additions) == 0 && len(deletions) == 0 {
		return nil, nil, errors.New(errors.TypeInvalidInput, ErrCodeInvalidPatchObject, "empty object patch request received, at least one of additions or deletions must be present")
	}

	for _, objectGroup := range additions {
		if err := ErrIfVerbNotValidForResource(verb, objectGroup.Resource); err != nil {
			return nil, nil, err
		}
	}

	for _, objectGroup := range deletions {
		if err := ErrIfVerbNotValidForResource(verb, objectGroup.Resource); err != nil {
			return nil, nil, err
		}
	}

	additionObjects, err := NewObjectsFromObjectGroups(additions)
	if err != nil {
		return nil, nil, err
	}

View on GitHub (pinned to 5069bf80b0)

Solutions

  1. Skip the PATCH call entirely when both lists are empty
  2. Ensure the diff logic actually maps changed groups into additions/deletions
  3. Validate client-side: if additions+deletions==0, show 'no changes' instead of submitting
  4. Check for accidental early-return in the code that populates the arrays

Example fix

// before
if err := patchObjects(nil, nil, verb); err != nil { ... }
// after
if len(additions) == 0 && len(deletions) == 0 { return nil }
addObjs, delObjs, err := coretypes.NewPatchableObjects(additions, deletions, verb)
Defensive patterns

Strategy: validation

Validate before calling

if (additions.length === 0 && deletions.length === 0) { /* skip PATCH */ }

Prevention

When it happens

Trigger: Calling the object patch API with {"additions":[],"deletions":[]} or omitting both arrays; programmatic patch builders that skip populating when a diff is empty.

Common situations: UI 'apply changes' button with no changes selected; diff calculators returning empty lists and still submitting; default-constructed request structs never filled.

Related errors


AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28). Data as JSON: /api/errors/221539161baefa09. Report an issue: GitHub.