{"record":{"id":"9848f04f0ec34483","repo":"plotly/plotly.js","slug":"unrecognized-gui-edit-key","errorCode":null,"errorMessage":"unrecognized GUI edit: ${key}","messagePattern":"unrecognized GUI edit: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/plot_api/plot_api.js","lineNumber":2458,"sourceCode":"                        // Only read the input layout once and stash the result,\n                        // so we get it before we start modifying it\n                        if (!(head in newAutorangeIn)) {\n                            var newContainer = nestedProperty(layout, head).get();\n                            newAutorangeIn[head] =\n                                newContainer &&\n                                (newContainer.autorange ||\n                                    (newContainer.autorange !== false &&\n                                        (!newContainer.range || newContainer.range.length !== 2)));\n                        }\n                        if (newAutorangeIn[head]) {\n                            newNP.set(undefinedToNull(nestedProperty(oldFullLayout, key).get()));\n                            continue;\n                        }\n                    }\n                }\n            }\n        } else {\n            Lib.warn('unrecognized GUI edit: ' + key);\n        }\n        // if we got this far, the new value was accepted as the new starting\n        // point (either because it changed or revision changed)\n        // so remove it from _preGUI for next time.\n        delete layoutPreGUI[key];\n\n        if (match && match.tail.slice(0, 6) === 'range[') {\n            newRangeAccepted[match.head] = 1;\n        }\n    }\n\n    // More special logic for `autorange`, since it interacts with `range`:\n    // If the new figure's matching `range` was kept, and `autorange`\n    // wasn't supplied explicitly in either the original or the new figure,\n    // we shouldn't alter that - but we may just have done that, so fix it.\n    for (var i = 0; i < bothInheritAutorange.length; i++) {\n        var axAttr = bothInheritAutorange[i];\n        if (newRangeAccepted[axAttr]) {","sourceCodeStart":2440,"sourceCodeEnd":2476,"githubUrl":"https://github.com/plotly/plotly.js/blob/1d090e0b5ffb8d0fdf6e0e4ff51d3f3cf67f1314/src/plot_api/plot_api.js#L2440-L2476","documentation":"This warning is emitted by Plotly.relayout when a GUI-edit key stored in layout._preGUI cannot be matched to a recognized relayout edit handler. The edit is skipped: the pre-GUI value is not restored/applied and the key is discarded. It almost always indicates a malformed attribute path or stale internal pre-GUI bookkeeping.","triggerScenarios":"Calling Plotly.relayout(gd, key, val) with a key that is not a recognized layout attribute path or known GUI edit (typo'd path, unrecognized nested/arrayed key, or an internal _preGUI key the dispatcher cannot classify).","commonSituations":"Typos in programmatic relayout calls (e.g. 'xaxis.rang'); custom interaction code writing unexpected keys into layout._preGUI; modebar/custom drag handlers interacting with relayout after traces or layout were regenerated.","solutions":["Check the key passed to Plotly.relayout for typos and verify it is a valid layout attribute path via Plotly.PlotSchema.","Re-render the figure with Plotly.react or Plotly.newPlot to clear stale _preGUI state instead of reusing the long-lived graph div.","If you extend interaction code, only write keys to pre-GUI state that the relayout dispatcher recognizes, or remove them before calling relayout."],"exampleFix":"// before\nPlotly.relayout(gd, 'xaxis.rang', [0, 10]);\n// after\nPlotly.relayout(gd, 'xaxis.range', [0, 10]);","handlingStrategy":"validation","validationCode":"function isValidLayoutKey(gd, key) {\n  const parts = key.split(/[\\[\\].]/).filter(Boolean);\n  let node = gd._fullLayout || {};\n  for (const p of parts) {\n    if (node == null || typeof node !== 'object' || !(p in node)) return false;\n    node = node[p];\n  }\n  return true;\n}\n// usage: if (isValidLayoutKey(gd, 'xaxis.range')) Plotly.relayout(gd, key, val);","typeGuard":"function isStringKey(v) {\n  return typeof v === 'string' && v.length > 0 && !v.startsWith('_');\n}","tryCatchPattern":null,"preventionTips":["Validate attribute paths against Plotly.PlotSchema before relayout.","Do not write custom keys into layout._preGUI.","Re-render with Plotly.react instead of reusing graph divs with accumulated GUI state.","Centralize relayout key constants to avoid typos."],"tags":["plotly","relayout","invalid-key","gui-state"],"backgroundTag":"unrecognized-attribute-key","analyzedSha":"1d090e0b5ffb8d0fdf6e0e4ff51d3f3cf67f1314","analyzedAt":"2026-09-02T22:03:39.906Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}