Why Lodash isFunction Fails on Async Generators

Lodash’s _.isFunction method historically misidentifies async generator functions (async function*) as non-functions across modern JavaScript runtimes and specific transpiled setups. This behavior primarily occurs in environments natively supporting ECMAScript 2018 (ES9)—such as Node.js 10+ and modern evergreen browsers—running unpatched versions of Lodash (prior to v4.17.11), as well as in hybrid environments where Babel and polyfill libraries alter object tags.

The Root Cause in Lodash's Type Detection

Lodash implements _.isFunction by inspecting the internal [[Class]] tag of an object using an internal baseGetTag utility, which wraps Object.prototype.toString.call(value).

In versions prior to 4.17.11, Lodash matched the tag against an explicit whitelist:

Because the ECMAScript 2018 specification introduced async generators after Lodash defined this whitelist, [object AsyncGeneratorFunction] was absent from the check. As a result, any object returning that specific tag evaluated to false.

Environments That Trigger the Misidentification

1. Modern Native JavaScript Engines (ES2018+)

Any runtime with native support for AsyncGeneratorFunction causes unpatched Lodash versions to misidentify async generators. Because the engine natively labels these functions with [object AsyncGeneratorFunction], Lodash rejects them:

In these environments, executing typeof (async function* () {}) returns "function", but passing that same declaration to _.isFunction returns false.

2. Transpiled and Polyfilled Build Environments

Projects using Babel, TypeScript, or Webpack in combination with runtime polyfills like core-js or regenerator-runtime encounter this issue in two distinct ways:

3. Cross-Realm and Sandboxed Contexts

In environments involving multiple execution realms—such as Node.js vm modules, Web Workers, or browser <iframe> elements—functions do not share the standard library prototypes of the host realm. Lodash relies strictly on baseGetTag rather than instanceof Function specifically to handle cross-realm objects. However, when an async generator originates from another realm in an ES2018+ host, the cross-realm tag check still yields [object AsyncGeneratorFunction], triggering the bug.

Resolution

The issue was addressed in Lodash version 4.17.11, which added [object AsyncGeneratorFunction] to the internal whitelist. Projects unable to upgrade Lodash can accurately detect async generators across all environments by using the native JavaScript check:

typeof fn === 'function'