appsmithorg/appsmith · error · Error
onModelChange expects a function as parameter
Error message
onModelChange expects a function as parameter
What it means
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.
Source
Thrown at app/client/src/widgets/wds/WDSCustomWidget/component/customWidgetscript.js:222
if (typeof fn !== "function") {
throw new Error("onThemeChange expects a function as parameter");
}
themeSubscribers.push(fn);
fn(window.appsmith.theme);
return () => {
// Unsubscribe from theme changes
const index = themeSubscribers.indexOf(fn);
if (index > -1) {
themeSubscribers.splice(index, 1);
}
};
},
onModelChange: (fn) => {
if (typeof fn !== "function") {
throw new Error("onModelChange expects a function as parameter");
}
modelSubscribers.push(fn);
fn(window.appsmith.model);
return () => {
// Unsubscribe from model changes
const index = modelSubscribers.indexOf(fn);
if (index > -1) {
modelSubscribers.splice(index, 1);
}
};
},
updateModel: (obj) => {
if (!obj || typeof obj !== "object") {
throw new Error("updateModel expects an object as parameter");
}View on GitHub (pinned to 8cd9021c24)
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.
Example fix
// before appsmith.onModelChange(syncState()); // invokes syncState, passes undefined // after appsmith.onModelChange(syncState); // passes the function reference
Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof onModelChangeHandler !== 'function') {
throw new TypeError('onModelChange expects a function');
}
const off = appsmith.onModelChange(onModelChangeHandler); Type guard
const isCallable = (v) => typeof v === 'function'; // usage if (isCallable(onModel)) appsmith.onModelChange(onModel);
Try / catch
try {
const off = appsmith.onModelChange(onModel);
} catch (e) {
console.error('onModelChange registration failed:', e.message);
} Prevention
- 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.
When it happens
Trigger: Calling appsmith.onModelChange(undefined), appsmith.onModelChange(null), appsmith.onModelChange({handleChange:fn}), appsmith.onModelChange('handleChange'), or appsmith.onModelChange() in the WDS widget.
Common situations: 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.
Related errors
- onThemeChange expects a function as parameter
- updateModel expects an object as parameter
- eventName should be a string
- contextObj should be an object
- onReady expects a function as parameter
AI-assisted analysis of appsmithorg/appsmith@8cd9021c24 (2026-08-12).
Data as JSON: /api/errors/22f8c138b66a940e.
Report an issue: GitHub.