zloirock/core-js · error · TypeError

Symbol is not a constructor

Error message

Symbol is not a constructor

What it means

core-js's Symbol polyfill implements Symbol as a plain function (not a native class) to work without new.target checks, so it manually throws a TypeError when called with new (detected via isPrototypeOf(SymbolPrototype, this)). Per spec, Symbol is not a constructor and must be called as Symbol(description).

Source

Thrown at packages/core-js/modules/es.symbol.constructor.js:168

};

var $getOwnPropertySymbols = function (O) {
  var IS_OBJECT_PROTOTYPE = O === ObjectPrototype;
  var names = nativeGetOwnPropertyNames(IS_OBJECT_PROTOTYPE ? ObjectPrototypeSymbols : toIndexedObject(O));
  var result = [];
  $forEach(names, function (key) {
    if (hasOwn(AllSymbols, key) && (!IS_OBJECT_PROTOTYPE || hasOwn(ObjectPrototype, key))) {
      push(result, AllSymbols[key]);
    }
  });
  return result;
};

// `Symbol` constructor
// https://tc39.es/ecma262/#sec-symbol-constructor
if (!NATIVE_SYMBOL) {
  $Symbol = function Symbol() {
    if (isPrototypeOf(SymbolPrototype, this)) throw new TypeError('Symbol is not a constructor');
    var description = !arguments.length || arguments[0] === undefined ? undefined : $toString(arguments[0]);
    var tag = uid(description);
    var setter = function (value) {
      var $this = this === undefined ? globalThis : this;
      if ($this === ObjectPrototype) call(setter, ObjectPrototypeSymbols, value);
      if (hasOwn($this, HIDDEN) && hasOwn($this[HIDDEN], tag)) $this[HIDDEN][tag] = false;
      var descriptor = createPropertyDescriptor(1, value);
      try {
        setSymbolDescriptor($this, tag, descriptor);
      } catch (error) {
        if (!(error instanceof RangeError)) throw error;
        fallbackDefineProperty($this, tag, descriptor);
      }
    };
    if (DESCRIPTORS && USE_SETTER) setSymbolDescriptor(ObjectPrototype, tag, { configurable: true, set: setter });
    return wrap(tag, description);
  };

View on GitHub (pinned to 84e45fba09)

Solutions

  1. Remove the new operator: call Symbol('description') directly.
  2. If you need a Symbol-like class instance, create your own wrapper object instead of new Symbol().
  3. Check generated/transpiled code for 'new Symbol' and fix the source or tsconfig (avoid typing the value as a constructable).
  4. On engines without native Symbol, keep the polyfill call form — core-js follows spec, so this throw is correct behavior.

Example fix

// before
const sym = new Symbol('id'); // TypeError
// after
const sym = Symbol('id');
Defensive patterns

Strategy: type-guard

Validate before calling

function safeSymbol(desc) {
  if (typeof Symbol !== 'function') throw new TypeError('Symbol unsupported');
  return Symbol(desc);
}

Type guard

function isSymbolValue(v) { return typeof v === 'symbol'; }
// ensure call form: typeof Symbol === 'function' && !usingNew — call Symbol(x) directly

Try / catch

try {
  const sym = new Symbol('id'); // replace with direct call
} catch (e) {
  if (e instanceof TypeError && /Symbol is not a constructor/.test(e.message)) {
    const sym = Symbol('id');
  } else throw e;
}

Prevention

When it happens

Trigger: new Symbol('x') — calling Symbol with the new operator; a transpiler/minifier or factory wrapper that emits new Sym(...) for a variable bound to Symbol; frameworks that genericly instantiate classes via new for a value that is actually the Symbol function.

Common situations: TypeScript/Babel downleveling a class-typed variable holding Symbol and calling new on it; IDE auto-complete adding 'new' before Symbol; migrating code from a wrapper library exposing newable Symbol-like class to core-js polyfilled Symbol on older engines (IE11 etc.); reflection utilities that blindly apply new to imported functions.

Related errors


AI-assisted analysis of zloirock/core-js@84e45fba09 (2026-08-30). Data as JSON: /api/errors/f73557202a2d0556. Report an issue: GitHub.