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

  1. Pass the exact string event name used when adding, e.g. observable.off('tap', handler)
  2. Fix the variable supplying the name so it is a defined string at call time
  3. Keep event names in a shared const map used by both on and off to avoid mismatches
  4. 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

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


AI-assisted analysis of NativeScript/NativeScript@6800aefa65 (2026-08-30). Data as JSON: /api/errors/8ce5365fd9e350a4. Report an issue: GitHub.