Automattic/mongoose · error · TypeError
Invalid subtype. Expected a number
Error message
Invalid subtype. Expected a number
What it means
MongooseBuffer.subtype() sets the BSON binary subtype of the buffer and validates its input: it must be a number (0-255 per the BSON spec). Passing a string like '4', null, or undefined throws a TypeError instead of storing an invalid subtype.
Source
Thrown at lib/types/buffer.js:278
* bson.BSON_BINARY_SUBTYPE_DEFAULT
* bson.BSON_BINARY_SUBTYPE_FUNCTION
* bson.BSON_BINARY_SUBTYPE_BYTE_ARRAY
* bson.BSON_BINARY_SUBTYPE_UUID
* bson.BSON_BINARY_SUBTYPE_MD5
* bson.BSON_BINARY_SUBTYPE_USER_DEFINED
*
* doc.buffer.subtype(bson.BSON_BINARY_SUBTYPE_UUID);
*
* @see bsonspec https://bsonspec.org/#/specification
* @param {Hex} subtype
* @api public
* @method subtype
* @memberOf MongooseBuffer
*/
MongooseBuffer.mixin.subtype = function(subtype) {
if (typeof subtype !== 'number') {
throw new TypeError('Invalid subtype. Expected a number');
}
if (this._subtype !== subtype) {
this._markModified();
}
this._subtype = subtype;
};
/*!
* Module exports.
*/
MongooseBuffer.Binary = Binary;
module.exports = MongooseBuffer;
View on GitHub (pinned to 49cdab0136)
Solutions
- Pass a number literal: doc.bin.subtype(4)
- Coerce config strings: doc.bin.subtype(Number(process.env.BIN_SUBTYPE))
- Use the BSON constant: import { BSON_BINARY_SUBTYPE_UUID } from 'bson'
Example fix
// before doc.bin.subtype(process.env.BIN_SUBTYPE); // string '4' // after doc.bin.subtype(Number(process.env.BIN_SUBTYPE));
Defensive patterns
Strategy: type-guard
Validate before calling
function setSubtype(buf, subtype) {
if (typeof subtype !== 'number' || !Number.isInteger(subtype) || subtype < 0 || subtype > 255) {
throw new TypeError('BSON subtype must be an integer 0-255');
}
buf.subtype(subtype);
} Type guard
function isValidSubtype(v) { return typeof v === 'number' && Number.isInteger(v) && v >= 0 && v <= 255; } Try / catch
try { buf.subtype(v); } catch (err) { if (/Expected a number/.test(err.message)) buf.subtype(Number(v)); else throw err; } Prevention
- Coerce config/env strings with Number() before passing to subtype()
- Use bson's BSON_BINARY_SUBTYPE_* constants instead of magic values
- Type the parameter as number in TS definitions to catch this at compile time
When it happens
Trigger: doc.bin.subtype('4') with a numeric string from config/env; doc.bin.subite(undefined) via a typo'd or unset variable; passing the string constant instead of bson.BSON_BINARY_SUBTYPE_UUID.
Common situations: Reading the subtype from environment variables or JSON config (always strings); passing values from untyped request payloads.
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
- Cannot convert a Buffer with subtype ${this._subtype} to a U
- Arguments must be aggregate pipeline operators
- Invalid addFields() argument. Must be an object
- Invalid project() argument. Must be string or object
- Invalid `path`. Must be either string or array. Got "${path}
AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21).
Data as JSON: /api/errors/8b71011b807b8410.
Report an issue: GitHub.