zloirock/core-js · error · TypeError
<symbol> is not a symbol (dynamic: tryToString(sym) + ' is n
Error message
<symbol> is not a symbol (dynamic: tryToString(sym) + ' is not a symbol')
What it means
Symbol.keyFor requires its argument to be an actual symbol registered in the global symbol registry. core-js validates with isSymbol and throws a TypeError prefixed with a tryToString of the argument (e.g. "42 is not a symbol"). With NATIVE_SYMBOL_REGISTRY native engines throw the equivalent 'x is not a symbol' TypeError; the polyfill version makes the offending value visible in the message.
Source
Thrown at packages/core-js/modules/es.symbol.key-for.js:15
'use strict';
var $ = require('../internals/export');
var hasOwn = require('../internals/has-own-property');
var isSymbol = require('../internals/is-symbol');
var tryToString = require('../internals/try-to-string');
var shared = require('../internals/shared');
var NATIVE_SYMBOL_REGISTRY = require('../internals/symbol-registry-detection');
var SymbolToStringRegistry = shared('symbol-to-string-registry');
// `Symbol.keyFor` method
// https://tc39.es/ecma262/#sec-symbol.keyfor
$({ target: 'Symbol', stat: true, forced: !NATIVE_SYMBOL_REGISTRY }, {
keyFor: function keyFor(sym) {
if (!isSymbol(sym)) throw new TypeError(tryToString(sym) + ' is not a symbol');
if (hasOwn(SymbolToStringRegistry, sym)) return SymbolToStringRegistry[sym];
}
});
View on GitHub (pinned to 84e45fba09)
Solutions
- Ensure the argument is a real symbol: convert string keys with Symbol.for(key) before calling keyFor.
- Check typeof v === 'symbol' before calling Symbol.keyFor.
- Remember keyFor returns undefined for Symbol()-created (unregistered) symbols — use Symbol.for if you need registry lookup.
- Fix the data source so symbols are not serialized to strings; store the registry key string separately instead.
Example fix
// before
const key = cache.get('myKey'); // stored as string
Symbol.keyFor(key); // TypeError: myKey is not a symbol
// after
const key = cache.get('myKey');
Symbol.keyFor(typeof key === 'string' ? Symbol.for(key) : key); Defensive patterns
Strategy: type-guard
Validate before calling
function keyForSafe(v) {
if (typeof v !== 'symbol') return undefined;
return Symbol.keyFor(v);
} Type guard
function isRegisteredSymbol(v) {
return typeof v === 'symbol' && Symbol.keyFor(v) !== undefined;
}
// usage: if (isRegisteredSymbol(sym)) const key = Symbol.keyFor(sym); Try / catch
try {
const key = Symbol.keyFor(sym);
} catch (e) {
if (e instanceof TypeError && /is not a symbol/.test(e.message)) {
// convert or reject: const key = Symbol.for(String(sym));
} else throw e;
} Prevention
- Always typeof-check for 'symbol' before Symbol.keyFor.
- Distinguish Symbol() (unregistered) from Symbol.for() (registered) in your code.
- Do not serialize Symbols through JSON/storage; persist the registry key string instead.
- Type API parameters as symbol, not any, to catch misuse at compile time.
When it happens
Trigger: Symbol.keyFor(42), Symbol.keyFor('foo'), Symbol.keyFor(Symbol('x')) — keyFor does NOT look up unregistered symbols created by Symbol(), only registry symbols from Symbol.for; passing a string that came from a deserialized key back to keyFor without converting via Symbol.for first.
Common situations: Round-tripping symbol keys through JSON/localStorage (Symbols stringify to 'Symbol(id)' strings) then calling keyFor on the string; caching layer storing registry keys as strings; code confusion between Symbol.for (register + keyFor lookup) and Symbol (unregistered); TypeScript types widening the parameter to any after an untyped API boundary.
Related errors
- Cannot convert a Symbol value to a number
- Symbol is not a constructor
- Promise can't be resolved itself
- ArrayBuffer expected
- Target is not a typed array
AI-assisted analysis of zloirock/core-js@84e45fba09 (2026-08-30).
Data as JSON: /api/errors/6ed12e3ade38b643.
Report an issue: GitHub.