{"record":{"id":"22f8c138b66a940e","repo":"appsmithorg/appsmith","slug":"onmodelchange-expects-a-function-as-parameter-22f8c1","errorCode":null,"errorMessage":"onModelChange expects a function as parameter","messagePattern":"onModelChange expects a function as parameter","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"app/client/src/widgets/wds/WDSCustomWidget/component/customWidgetscript.js","lineNumber":222,"sourceCode":"          if (typeof fn !== \"function\") {\n            throw new Error(\"onThemeChange expects a function as parameter\");\n          }\n\n          themeSubscribers.push(fn);\n          fn(window.appsmith.theme);\n\n          return () => {\n            // Unsubscribe from theme changes\n            const index = themeSubscribers.indexOf(fn);\n\n            if (index > -1) {\n              themeSubscribers.splice(index, 1);\n            }\n          };\n        },\n        onModelChange: (fn) => {\n          if (typeof fn !== \"function\") {\n            throw new Error(\"onModelChange expects a function as parameter\");\n          }\n\n          modelSubscribers.push(fn);\n          fn(window.appsmith.model);\n\n          return () => {\n            // Unsubscribe from model changes\n            const index = modelSubscribers.indexOf(fn);\n\n            if (index > -1) {\n              modelSubscribers.splice(index, 1);\n            }\n          };\n        },\n        updateModel: (obj) => {\n          if (!obj || typeof obj !== \"object\") {\n            throw new Error(\"updateModel expects an object as parameter\");\n          }","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/appsmithorg/appsmith/blob/8cd9021c24cdbea1c3c12c966073708e83db60c2/app/client/src/widgets/wds/WDSCustomWidget/component/customWidgetscript.js#L204-L240","documentation":"Thrown by window.appsmith.onModelChange() in the WDS Custom Widget iframe. Identical contract to the legacy widget's onModelChange: it registers a subscriber invoked on every model change and once immediately with the current model, then pushes fn into modelSubscribers. Rejects non-function arguments.","triggerScenarios":"Calling appsmith.onModelChange(undefined), appsmith.onModelChange(null), appsmith.onModelChange({handleChange:fn}), appsmith.onModelChange('handleChange'), or appsmith.onModelChange() in the WDS widget.","commonSituations":"Referencing a handler constant that was tree-shaken or declared later in the module; passing the result of calling the handler; copy-pasting sample code that expected a named import that was not added.","solutions":["Pass a function reference: appsmith.onModelChange(onModelChange).","Use an inline arrow receiving the model: appsmith.onModelChange((model) => { state.value = model.value }).","If registration is conditional, guard first: if (typeof fn === 'function') appsmith.onModelChange(fn).","Capture and call the returned unsubscribe on cleanup."],"exampleFix":"// before\nappsmith.onModelChange(syncState()); // invokes syncState, passes undefined\n\n// after\nappsmith.onModelChange(syncState); // passes the function reference","handlingStrategy":"type-guard","validationCode":"if (typeof onModelChangeHandler !== 'function') {\n  throw new TypeError('onModelChange expects a function');\n}\nconst off = appsmith.onModelChange(onModelChangeHandler);","typeGuard":"const isCallable = (v) => typeof v === 'function';\n\n// usage\nif (isCallable(onModel)) appsmith.onModelChange(onModel);","tryCatchPattern":"try {\n  const off = appsmith.onModelChange(onModel);\n} catch (e) {\n  console.error('onModelChange registration failed:', e.message);\n}","preventionTips":["Pass the function reference; it is invoked immediately with the current model.","Hoist named handlers or assign const arrows before registering.","Store the returned unsubscribe and call it on iframe cleanup.","Lint for appsmith.onModelChange(\\w+\\(\\)) to catch accidental invocations."],"tags":["custom-widget","wds","appsmith-api","parameter-validation","javascript"],"backgroundTag":null,"analyzedSha":"8cd9021c24cdbea1c3c12c966073708e83db60c2","analyzedAt":"2026-08-12T22:14:19.293Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}