{"record":{"id":"16e84af2194d40d8","repo":"octobercms/october","slug":"invalid-update-value-the-correct-format-is-an-obj","errorCode":null,"errorMessage":"Invalid update value. The correct format is an object ({...})","messagePattern":"Invalid update value\\. The correct format is an object \\((.+?)\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"modules/system/assets/js/framework.js","lineNumber":383,"sourceCode":"      }\n      var xsrfToken = this.getXSRFToken();\n      if (xsrfToken) {\n        headers[\"X-XSRF-TOKEN\"] = xsrfToken;\n      }\n      var csrfToken = this.getCSRFToken();\n      if (csrfToken) {\n        headers[\"X-CSRF-TOKEN\"] = csrfToken;\n      }\n      if (options.headers && options.headers.constructor === {}.constructor) {\n        Object.assign(headers, options.headers);\n      }\n      return headers;\n    }\n    extractPartials(update = {}, selfPartial) {\n      var result = [];\n      if (update) {\n        if (typeof update !== \"object\") {\n          throw new Error(\"Invalid update value. The correct format is an object ({...})\");\n        }\n        for (var partial in update) {\n          if (partial === \"_self\" && selfPartial) {\n            result.push(selfPartial);\n          } else {\n            result.push(partial);\n          }\n        }\n      }\n      return result.join(\"&\");\n    }\n    getCSRFToken() {\n      var tag = document.querySelector('meta[name=\"csrf-token\"]');\n      return tag ? tag.getAttribute(\"content\") : null;\n    }\n    getXSRFToken() {\n      var cookieValue = null;\n      if (document.cookie && document.cookie != \"\") {","sourceCodeStart":365,"sourceCodeEnd":401,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/system/assets/js/framework.js#L365-L401","documentation":"Thrown by Options.extractPartials() in October CMS's AJAX framework when the update option passed to a request is not an object. The update map associates partial names with target CSS selectors ({'partialName': '#target'}, plus the special '_self' key); extractPartials iterates its keys to build the X-AJAX-PARTIALS header, so a string, number or other non-object type is rejected before the request is sent.","triggerScenarios":"oc.request(el, 'onSearch', {update: '#result'}) - a bare selector string instead of {resultPartial: '#result'}; passing update: 'partialName'; passing a JSON-encoded string instead of a parsed object; update: true from a boolean flag misuse.","commonSituations":"Developers assuming update takes a selector string like old jQuery plugins; passing a serialized JSON string where the options expect a literal object; copy-pasting from data-request-update attribute syntax (string form) into JS options (object form); forgetting _self must be a key, not a value.","solutions":["Convert the value to the partial->selector map: {update: {'search-results': '#result'}}","If you only want the element's own partial, use the _self key or options.partial instead of a string","When receiving the map as JSON text, JSON.parse it before passing it into options"],"exampleFix":"// before\noc.request(el, 'onSearch', { update: '#result' });\n\n// after\noc.request(el, 'onSearch', { update: { 'search-results': '#result' } });","handlingStrategy":"type-guard","validationCode":"const isPlainObject = (v) => Object.prototype.toString.call(v) === '[object Object]';\n\nif (isPlainObject(options.update)) {\n  oc.request(el, 'onSearch', options);\n} else {\n  console.error('update must map partial names to selectors, e.g. {\"results\": \"#list\"}');\n}","typeGuard":"const isUpdateMap = (v) => !v || (Object.prototype.toString.call(v) === '[object Object]' && Object.values(v).every((s) => typeof s === 'string'));","tryCatchPattern":"try { oc.request(el, 'onSearch', opts); } catch (e) { if (/Invalid update value/.test(e.message)) { console.error('Pass update as {partial: \"selector\"}'); return; } throw e; }","preventionTips":["Remember the JS option is an object; only the data-request-update attribute uses string form","Use '_self' as a key when the element's own partial should refresh","JSON.parse serialized update maps before passing them as options"],"tags":["ajax","options","partials","validation","frontend"],"backgroundTag":"invalid-ajax-option","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}