SigNoz/signoz · error
ErrCodeDashboardInvalidPatch
ErrCodeDashboardInvalidPatch
Error message
JSON Patch could not be applied to the target dashboard
What it means
Apply in perses_dashboard_patch.go runs a JSON Patch (RFC 6902) against the marshaled existing dashboard using patch.ApplyWithOptions with AllowMissingPathOnRemove and EnsurePathExistsOnAdd. If the evanphx/json-patch library rejects the operation sequence (unparseable patch, invalid op, path escaping failure, mismatched types), the error is wrapped as ErrCodeDashboardInvalidPatch with the underlying patch error attached via WithAdditional.
Source
Thrown at pkg/types/dashboardtypes/perses_dashboard_patch.go:76
if err != nil {
return errors.New(errors.TypeInvalidInput, ErrCodeDashboardInvalidPatch, "request body is not a valid RFC 6902 JSON Patch document").WithAdditional(err.Error())
}
if err := json.Unmarshal(data, &p.Ops); err != nil {
return errors.New(errors.TypeInvalidInput, ErrCodeDashboardInvalidPatch, "request body is not a valid RFC 6902 JSON Patch document").WithAdditional(err.Error())
}
p.patch = patch
return nil
}
func (p PatchableDashboardV2) Apply(existing *DashboardV2) (*UpdatableDashboardV2, error) {
existingAsUpdatable := existing.toUpdatableDashboardV2()
raw, err := json.Marshal(existingAsUpdatable)
if err != nil {
return nil, errors.WrapInternalf(err, errors.CodeInternal, "marshal existing dashboard for patch")
}
patched, err := p.patch.ApplyWithOptions(raw, &jsonpatch.ApplyOptions{AllowMissingPathOnRemove: true, EnsurePathExistsOnAdd: true})
if err != nil {
return nil, errors.Wrap(err, errors.TypeInvalidInput, ErrCodeDashboardInvalidPatch, "JSON Patch could not be applied to the target dashboard").WithAdditional(err.Error())
}
out := &UpdatableDashboardV2{}
if err := json.Unmarshal(patched, out); err != nil {
return nil, err
}
return out, nil
}
View on GitHub (pinned to 5069bf80b0)
Solutions
- Validate the patch is a legal RFC 6902 document (jsonpatch.Decode) before applying
- Retry with a fresh GET of the dashboard and regenerate the patch against current state
- Check the attached underlying error (WithAdditional) to see the exact failing op and path
- Fall back to a full PUT/update instead of a patch if the path churn is expected
Example fix
// before
patch := []byte(`[{"op":"replace","path":"/panels/5","value":{}}]`)
updated, err := p.Apply(existing)
// after
patch := []byte(`[{"op":"replace","path":"/panels/5/title","value":"latency"}]`)
updated, err := p.Apply(existing) Defensive patterns
Strategy: validation
Validate before calling
if _, err := jsonpatch.DecodePatch(patchBytes); err != nil {
return fmt.Errorf("malformed patch: %w", err)
}
updated, err := p.Apply(existing) Try / catch
out, err := patch.Apply(existing)
if err != nil {
// re-fetch and regenerate patch once, then give up with a clear message
fresh := getLatestDashboard(id)
out, err = patch.Apply(fresh)
} Prevention
- Keep patch ops narrow (leaf paths like /panels/0/title)
- Build patches from a just-fetched copy of the resource
- Prefer full update over patch when schema versions differ
When it happens
Trigger: Calling PatchV2 (or Apply directly) with a JSON Patch document whose ops reference paths that do not match the dashboard structure (beyond what AllowMissingPathOnRemove/EnsurePathExistsOnAdd tolerate), use an unknown op, or try to replace/add a value of the wrong type at a path (e.g. replacing an array with an object).
Common situations: Clients generating patches from a stale copy of the dashboard (concurrent edits moved/renamed fields); patch tools emitting copy/move ops with malformed from paths; UI diffing after a dashboard schema upgrade between versions.
Related errors
- dashboard_invalid_patch
- CodeLicenseUnavailable
- ErrCodePublicDashboardInvalidInput
- ErrCodeInvalidPatchObject
- invalid_input
AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28).
Data as JSON: /api/errors/35c95c4cd0670476.
Report an issue: GitHub.