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() inside a legacy Custom Widget's iframe sandbox. The method registers a subscriber that is invoked whenever the widget's model (the JSON object exchanged with the parent Appsmith app) changes; it also calls the callback immediately with the current model. It refuses any argument that is not a function because it must later invoke fn(window.appsmith.model) and push fn into modelSubscribers.
Source
Thrown at app/client/src/widgets/CustomWidget/component/customWidgetscript.js:242
if (typeof fn !== "function") {
throw new Error("onUiChange expects a function as parameter");
}
uiSubscribers.push(fn);
fn(window.appsmith.ui);
return () => {
// Unsubscribe from UI changes
const index = uiSubscribers.indexOf(fn);
if (index > -1) {
uiSubscribers.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 directly: appsmith.onModelChange(handleChange) where handleChange is a hoisted function or an initialized const arrow.
- If using an inline handler, pass the arrow itself: appsmith.onModelChange((model) => { ... }).
- Check for undefined before registering if the handler is optional: if (typeof handler === 'function') appsmith.onModelChange(handler).
- Store the returned unsubscribe function and call it on cleanup to avoid duplicate subscriptions.
Example fix
// before appsmith.onModelChange(handleChange()); // invokes handleChange, passes its (undefined) return // after appsmith.onModelChange(handleChange); // passes the function reference itself
Defensive patterns
Strategy: type-guard
Validate before calling
// Before registering, confirm fn is callable
if (typeof handler !== 'function') {
throw new TypeError('onModelChange handler must be a function, got ' + typeof handler);
}
const unsubscribe = appsmith.onModelChange(handler); Type guard
const isCallable = (v) => typeof v === 'function';
// usage
if (isCallable(handleChange)) {
appsmith.onModelChange(handleChange);
} Try / catch
try {
const off = appsmith.onModelChange(handleChange);
} catch (e) {
console.error('onModelChange registration failed:', e.message);
} Prevention
- Always pass a function reference, never the result of invoking it.
- Lint for appsmith.onModelChange(\w+\(\)) patterns where the handler is invoked instead of passed.
- Hoist named handler functions so they are defined before the onModelChange call.
- Keep the returned unsubscribe function and call it on iframe teardown.
When it happens
Trigger: Calling appsmith.onModelChange(undefined), appsmith.onModelChange(null), appsmith.onModelChange({handleChange:...}), or appsmith.onModelChange('handleChange') from the iframe's script. Also triggered by passing the result of a void expression, e.g. appsmith.onModelChange(someFn()) where someFn returns undefined.
Common situations: Refactoring iframe code and forgetting to pass the callback; referencing an undefined helper; copy-pasting from a sample that used a named function declaration that was later renamed; passing an arrow assigned to a const that lives in a different scope and resolved to undefined at call time.
Related errors
- updateModel expects an object as parameter
- eventName should be a string
- contextObj should be an object
- onReady expects a function as parameter
- onThemeChange expects a function as parameter
AI-assisted analysis of appsmithorg/appsmith@8cd9021c24 (2026-08-12).
Data as JSON: /api/errors/6d1c6da5fa202ccd.
Report an issue: GitHub.