Automattic/mongoose · error · TypeError
Mongoose maps only support string keys, got ${keyType}
Error message
Mongoose maps only support string keys, got ${keyType} What it means
checkValidKey() guards every key written to a MongooseMap. Because Maps are persisted as plain MongoDB objects, keys must be strings; setting a numeric, boolean, symbol, or object key throws a TypeError.
Source
Thrown at lib/types/map.js:355
Object.defineProperty(MongooseMap.prototype, '$__deferredCalls', {
enumerable: false,
writable: false,
configurable: false,
value: true
});
/**
* Since maps are stored as objects under the hood, keys must be strings
* and can't contain any invalid characters
* @param {string} key
* @api private
*/
function checkValidKey(key) {
const keyType = typeof key;
if (keyType !== 'string') {
throw new TypeError(`Mongoose maps only support string keys, got ${keyType}`);
}
if (key.startsWith('$')) {
throw new Error(`Mongoose maps do not support keys that start with "$", got "${key}"`);
}
if (key.includes('.')) {
throw new Error(`Mongoose maps do not support keys that contain ".", got "${key}"`);
}
if (specialProperties.has(key)) {
throw new Error(`Mongoose maps do not support reserved key name "${key}"`);
}
}
module.exports = MongooseMap;
View on GitHub (pinned to 49cdab0136)
Solutions
- Convert keys to strings when setting: doc.map.set(String(key), value)
- Declare the Map with string-friendly keys at the boundary: { type: Map, of: String } and normalize input before assignment
- For ObjectId keys, use the hex string: doc.map.set(id.toHexString(), v)
Example fix
// before doc.clicks.set(42, 'x'); // TypeError // after doc.clicks.set(String(42), 'x');
Defensive patterns
Strategy: type-guard
Validate before calling
function safeMapSet(map, key, value) {
if (typeof key !== 'string') key = String(key);
map.set(key, value);
} Type guard
function isStringKey(key) { return typeof key === 'string'; } Try / catch
try { doc.map.set(key, val); } catch (err) { if (/only support string keys/.test(err.message)) doc.map.set(String(key), val); else throw err; } Prevention
- Normalize external keys with String() before Map writes
- Use toHexString() for ObjectId keys
- Unit-test Map writes with the exact key types your ingesters produce
When it happens
Trigger: doc.map.set(123, 'x'); doc.map.set(user.id, ...) where user.id is a number or ObjectId; constructing the Map from Object.entries of typed input; using m.set(Symbol('k'), v).
Common situations: Numeric IDs from external systems used as Map keys; values coming from typed APIs, query strings, or BSON types that are not strings.
Related errors
- Mongoose maps do not support keys that start with "$", got "
- Mongoose maps do not support keys that contain ".", got "${k
- Mongoose maps do not support reserved key name "${key}"
- Arguments must be aggregate pipeline operators
- Invalid addFields() argument. Must be an object
AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21).
Data as JSON: /api/errors/3ee09f83900816be.
Report an issue: GitHub.