appsmithorg/appsmith · error · Error

onReady expects a function as parameter

Error message

onReady expects a function as parameter

What it means

Thrown by window.appsmith.onReady() in the WDS Custom Widget iframe. onReady stores a single readiness callback (onReady = fn) and invokes it synchronously if the host has already signalled readiness and it has not been called yet. A non-function argument is rejected because the method may immediately invoke it.

Source

Thrown at app/client/src/widgets/wds/WDSCustomWidget/component/customWidgetscript.js:266

          channel.postMessage(EVENTS.CUSTOM_WIDGET_UPDATE_MODEL, obj);
        },
        triggerEvent: (eventName, contextObj) => {
          if (typeof eventName !== "string") {
            throw new Error("eventName should be a string");
          } else if (contextObj && typeof contextObj !== "object") {
            throw new Error("contextObj should be an object");
          }

          // Send a trigger event message to the parent
          channel.postMessage(EVENTS.CUSTOM_WIDGET_TRIGGER_EVENT, {
            eventName,
            contextObj,
          });
        },
        model: {},
        onReady: (fn) => {
          if (typeof fn !== "function") {
            throw new Error("onReady expects a function as parameter");
          }

          onReady = fn;

          if (isReady && !isReadyCalled && onReady) {
            onReady();
            isReadyCalled = true;
          }
        },
      },
    });
  }

  // Listen for the 'load' event and send READY message to the parent
  window.addEventListener("load", () => {
    channel.postMessage(EVENTS.CUSTOM_WIDGET_READY);
  });
}

View on GitHub (pinned to 8cd9021c24)

Solutions

  1. Pass the function reference: appsmith.onReady(bootstrap).
  2. Use an inline arrow: appsmith.onReady(() => mount(appsmith.model)).
  3. Keep the callback idempotent; only the last registered one is retained.
  4. Do bootstrap work inside the callback, not at top-level, so the host channel is ready.

Example fix

// before
appsmith.onReady(init()); // invokes init, passes undefined

// after
appsmith.onReady(init); // passes the function reference
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof readyHandler !== 'function') {
  throw new TypeError('onReady expects a function');
}
appsmith.onReady(readyHandler);

Type guard

const isCallable = (v) => typeof v === 'function';

// usage
if (isCallable(bootstrap)) appsmith.onReady(bootstrap);

Try / catch

try {
  appsmith.onReady(bootstrap);
} catch (e) {
  console.error('onReady registration failed:', e.message);
}

Prevention

When it happens

Trigger: Calling appsmith.onReady(undefined), appsmith.onReady(null), appsmith.onReady('init'), appsmith.onReady({bootstrap:fn}), or appsmith.onReady() with no argument in the WDS widget.

Common situations: Invoking the init function instead of passing it; passing a config object containing the handler; calling onReady twice and omitting the argument the second time.

Related errors


AI-assisted analysis of appsmithorg/appsmith@8cd9021c24 (2026-08-12). Data as JSON: /api/errors/830e4ecb0940a88a. Report an issue: GitHub.