{"record":{"id":"35c95c4cd0670476","repo":"SigNoz/signoz","slug":"errcodedashboardinvalidpatch","errorCode":"ErrCodeDashboardInvalidPatch","errorMessage":"JSON Patch could not be applied to the target dashboard","messagePattern":"JSON Patch could not be applied to the target dashboard","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"pkg/types/dashboardtypes/perses_dashboard_patch.go","lineNumber":76,"sourceCode":"\tif err != nil {\n\t\treturn errors.New(errors.TypeInvalidInput, ErrCodeDashboardInvalidPatch, \"request body is not a valid RFC 6902 JSON Patch document\").WithAdditional(err.Error())\n\t}\n\tif err := json.Unmarshal(data, &p.Ops); err != nil {\n\t\treturn errors.New(errors.TypeInvalidInput, ErrCodeDashboardInvalidPatch, \"request body is not a valid RFC 6902 JSON Patch document\").WithAdditional(err.Error())\n\t}\n\tp.patch = patch\n\treturn nil\n}\n\nfunc (p PatchableDashboardV2) Apply(existing *DashboardV2) (*UpdatableDashboardV2, error) {\n\texistingAsUpdatable := existing.toUpdatableDashboardV2()\n\traw, err := json.Marshal(existingAsUpdatable)\n\tif err != nil {\n\t\treturn nil, errors.WrapInternalf(err, errors.CodeInternal, \"marshal existing dashboard for patch\")\n\t}\n\tpatched, err := p.patch.ApplyWithOptions(raw, &jsonpatch.ApplyOptions{AllowMissingPathOnRemove: true, EnsurePathExistsOnAdd: true})\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, errors.TypeInvalidInput, ErrCodeDashboardInvalidPatch, \"JSON Patch could not be applied to the target dashboard\").WithAdditional(err.Error())\n\t}\n\tout := &UpdatableDashboardV2{}\n\tif err := json.Unmarshal(patched, out); err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n","sourceCodeStart":58,"sourceCodeEnd":84,"githubUrl":"https://github.com/SigNoz/signoz/blob/5069bf80b08f1f00d7e014eccc09902f9871004f/pkg/types/dashboardtypes/perses_dashboard_patch.go#L58-L84","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\npatch := []byte(`[{\"op\":\"replace\",\"path\":\"/panels/5\",\"value\":{}}]`)\nupdated, err := p.Apply(existing)\n\n// after\npatch := []byte(`[{\"op\":\"replace\",\"path\":\"/panels/5/title\",\"value\":\"latency\"}]`)\nupdated, err := p.Apply(existing)","handlingStrategy":"validation","validationCode":"if _, err := jsonpatch.DecodePatch(patchBytes); err != nil {\n    return fmt.Errorf(\"malformed patch: %w\", err)\n}\nupdated, err := p.Apply(existing)","typeGuard":null,"tryCatchPattern":"out, err := patch.Apply(existing)\nif err != nil {\n    // re-fetch and regenerate patch once, then give up with a clear message\n    fresh := getLatestDashboard(id)\n    out, err = patch.Apply(fresh)\n}","preventionTips":["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"],"tags":["json-patch","dashboard","rfc6902","patch"],"backgroundTag":"json-patch-apply-failed","analyzedSha":"5069bf80b08f1f00d7e014eccc09902f9871004f","analyzedAt":"2026-08-28T06:22:12.824Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}