NativeScript/NativeScript · error · TypeError
Events name(s) must be string.
Error message
Events name(s) must be string.
What it means
Observable.removeEventListener requires eventName to be a string and throws a TypeError otherwise. This mirrors the addEventListener check so removal cannot silently no-op on bad keys.
Source
Thrown at packages/core/data/observable/index.ts:249
list.push({
callback,
thisArg,
once,
});
}
/**
* Removes listener(s) for the specified event name.
* @param eventName Name of the event to attach to.
* @param callback An optional parameter pointing to a specific listener. If not defined, all listeners for the event names will be removed.
* @param thisArg An optional parameter which when set will be used to refine search of the correct callback which will be removed as event listener.
*/
public removeEventListener(eventName: string, callback?: (data: EventData) => void, thisArg?: any): void {
thisArg = thisArg || undefined;
if (typeof eventName !== 'string') {
throw new TypeError('Events name(s) must be string.');
}
if (callback && typeof callback !== 'function') {
throw new TypeError('callback must be function.');
}
const entries = this._observers[eventName];
if (!entries) {
return;
}
Observable.innerRemoveEventListener(entries, callback, thisArg);
if (!entries.length) {
// Clear all entries of this type
delete this._observers[eventName];
}
}View on GitHub (pinned to 6800aefa65)
Solutions
- Pass the exact string event name used when adding, e.g. observable.off('tap', handler)
- Fix the variable supplying the name so it is a defined string at call time
- Keep event names in a shared const map used by both on and off to avoid mismatches
- Guard with typeof name === 'string' before calling off for dynamically supplied names
Example fix
// before
observable.off(args.eventName); // args.eventName is undefined
// after
observable.off('tap', handler); Defensive patterns
Strategy: type-guard
Validate before calling
function safeOff(obs, eventName, cb) {
if (typeof eventName !== 'string') {
console.warn('observable.off: eventName is not a string:', eventName);
return;
}
obs.off(eventName, cb);
} Type guard
const isEventName = (v: unknown): v is string => typeof v === 'string' && v.length > 0;
Try / catch
try {
observable.off(name, handler);
} catch (e) {
if (e instanceof TypeError && /must be string/.test(e.message)) {
console.error('Bad event name on off():', name);
}
} Prevention
- Use the same string constants for on and off — never reconstruct the name
- Pass the event name string, not an EventData object, to off()
- Destructure handlers/names carefully in lifecycle cleanup code
- Validate dynamic names with typeof before calling removeEventListener
When it happens
Trigger: Calling observable.off(null), off(undefined, cb), or off(eventNameVar) where eventNameVar is not a string; also off(eventData) mistakenly passing an EventData object instead of the name.
Common situations: Storing event names in a lookup that returns undefined, calling off inside a handler with the EventData object instead of the name string, framework code that lost the original name via destructuring.
Understand the failure class
Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.
Related errors
- Event name must be a string.
- Callback, if provided, must be a function.
- callback must be function.
- Callback, if provided, must be function.
- Callback must be a function.
AI-assisted analysis of NativeScript/NativeScript@6800aefa65 (2026-08-30).
Data as JSON: /api/errors/8ce5365fd9e350a4.
Report an issue: GitHub.