This MongoDB error occurs when a query or aggregation pipeline attempts to compare a field value to undefined, which is not a valid comparison type. MongoDB cannot directly compare values to undefined because it treats undefined differently from null and missing fields.
This error is thrown by MongoDB when executing a query or aggregation pipeline that contains a comparison operation with an undefined value. MongoDB's query engine encounters this when trying to evaluate expressions that reference undefined values, particularly in $expr operators, aggregation pipeline stages, or comparison operators within conditional logic. MongoDB has multiple representations for "no value": null, missing fields, and the deprecated BSON undefined type (type number 6). When JavaScript code passes undefined to a MongoDB query, the driver typically converts it to null automatically, but in certain contexts—especially in aggregation expressions, $expr operators, or when using legacy drivers—the undefined value can reach the query parser and cause a TypeMismatch error. The error commonly appears in aggregation pipelines where conditional expressions ($cond, $switch) or comparison operators ($eq, $gt, $lt) attempt to evaluate against undefined. Starting with MongoDB 8.0, the handling of null and undefined in equality comparisons has become stricter, making this error more common when migrating legacy code.
First, examine the query or aggregation pipeline causing the error. Look for undefined values being passed:
// Problem: Undefined value in query
const userId = req.params.userId; // Might be undefined
db.collection('users').find({ _id: userId }); // TypeMismatch error
// Solution: Validate before querying
const userId = req.params.userId;
if (!userId) {
throw new Error('User ID is required');
}
db.collection('users').find({ _id: userId });Check aggregation expressions for undefined comparisons:
// Problem: Comparing to undefined in $expr
db.collection('products').find({
$expr: {
$eq: ['$category', undefined] // Cannot compare to undefined
}
});
// Solution: Use null instead
db.collection('products').find({
$expr: {
$eq: ['$category', null]
}
});MongoDB can compare values to null but not to undefined. Convert undefined values to null:
// Problem: Passing undefined from JavaScript
const filters = {
status: searchParams.status, // Might be undefined
category: searchParams.category // Might be undefined
};
db.collection('items').find(filters);
// Solution: Filter out undefined values
const filters = {};
if (searchParams.status !== undefined) {
filters.status = searchParams.status;
}
if (searchParams.category !== undefined) {
filters.category = searchParams.category;
}
db.collection('items').find(filters);
// Or use a utility function
const cleanFilters = Object.fromEntries(
Object.entries({
status: searchParams.status,
category: searchParams.category
}).filter(([_, value]) => value !== undefined)
);
db.collection('items').find(cleanFilters);When working with aggregation pipelines, use $ifNull to handle undefined or null values:
// Problem: Comparison fails if field is missing
db.collection('orders').aggregate([
{
$match: {
$expr: {
$gt: ['$discountAmount', 0] // Error if discountAmount is undefined
}
}
}
]);
// Solution: Use $ifNull to provide a default value
db.collection('orders').aggregate([
{
$match: {
$expr: {
$gt: [{ $ifNull: ['$discountAmount', 0] }, 0]
}
}
}
]);
// Or handle missing fields explicitly
db.collection('orders').aggregate([
{
$addFields: {
discountAmount: { $ifNull: ['$discountAmount', 0] }
}
},
{
$match: {
discountAmount: { $gt: 0 }
}
}
]);To query for null or missing fields, use the correct operators instead of comparing to undefined:
// Problem: Trying to find documents where field is undefined
db.collection('users').find({
email: undefined // Error: cannot compare to undefined
});
// Solution: Query for null OR missing field
db.collection('users').find({
email: null // Matches null values AND missing fields (before MongoDB 8.0)
});
// For MongoDB 8.0+: null no longer matches missing fields
// To match ONLY null values:
db.collection('users').find({
email: { $eq: null },
email: { $exists: true } // Field exists but is null
});
// To match missing fields:
db.collection('users').find({
email: { $exists: false }
});
// To match null OR missing:
db.collection('users').find({
$or: [
{ email: null },
{ email: { $exists: false } }
]
});Use $cond with proper null handling instead of relying on undefined:
// Problem: Conditional with undefined comparison
db.collection('products').aggregate([
{
$project: {
displayPrice: {
$cond: {
if: { $eq: ['$salePrice', undefined] }, // Error
then: '$regularPrice',
else: '$salePrice'
}
}
}
}
]);
// Solution 1: Use $ifNull
db.collection('products').aggregate([
{
$project: {
displayPrice: {
$ifNull: ['$salePrice', '$regularPrice']
}
}
}
]);
// Solution 2: Check field existence
db.collection('products').aggregate([
{
$project: {
displayPrice: {
$cond: {
if: { $gt: ['$salePrice', null] }, // true if field exists and not null
then: '$salePrice',
else: '$regularPrice'
}
}
}
}
]);If using Mongoose, ensure undefined values are filtered before queries:
// Problem: Mongoose passes undefined values
const User = mongoose.model('User');
const filters = {
email: req.query.email, // May be undefined
status: req.query.status // May be undefined
};
await User.find(filters); // May cause errors
// Solution 1: Set Mongoose to strip undefined
mongoose.set('strictQuery', true);
// Solution 2: Clean the query object manually
const cleanQuery = Object.fromEntries(
Object.entries({
email: req.query.email,
status: req.query.status
}).filter(([_, v]) => v !== undefined && v !== null && v !== '')
);
await User.find(cleanQuery);
// Solution 3: Build query conditionally
const query = {};
if (req.query.email) query.email = req.query.email;
if (req.query.status) query.status = req.query.status;
await User.find(query);MongoDB 8.0 Breaking Change:
Starting in MongoDB 8.0, equality match expressions with null ({field: null}) no longer match documents where the field is undefined or missing. This is a breaking change from earlier versions. To match both null and missing fields in MongoDB 8.0+, use:
db.collection.find({
$or: [
{ field: null },
{ field: { $exists: false } }
]
});BSON Undefined Type:
The deprecated BSON undefined type (type 6) should never be used in modern MongoDB applications. Modern drivers automatically convert JavaScript undefined to null. If you're working with legacy databases that contain BSON undefined values, you can query them using:
db.collection.find({ field: { $type: 6 } }); // Query for deprecated undefined typeTo migrate these values to null:
db.collection.updateMany(
{ field: { $type: 6 } },
{ $set: { field: null } }
);Expression Operator Performance:
When using $expr in queries, note that indexes may not be used for comparisons where the operand is undefined, null, or an array. This can significantly impact performance. If possible, restructure queries to use standard query operators instead of $expr.
Type Coercion in Aggregation:
In aggregation pipelines, type coercion rules differ from regular queries. The $cmp operator and related comparison operators have specific rules for type ordering where null has a defined position in the type sort order, but undefined does not.
Debugging Strategy:
To identify where undefined values are introduced, add logging to your query construction:
const pipeline = [
{ $match: { /* ... */ } },
{ $project: { /* ... */ } }
];
console.log('Pipeline:', JSON.stringify(pipeline, null, 2));
// undefined values will show as missing from JSON outputTypeScript Type Safety:
Use TypeScript strict null checks to prevent undefined from reaching MongoDB queries:
interface UserFilter {
email?: string; // Optional but never undefined when present
status: 'active' | 'inactive'; // Required, no undefined
}
const filters: Partial<UserFilter> = {};
if (email !== undefined) filters.email = email;StaleShardVersion: shard version mismatch
How to fix "StaleShardVersion: shard version mismatch" in MongoDB
MongoOperationTimeoutError: Operation timed out
How to fix "MongoOperationTimeoutError: Operation timed out" in MongoDB
MongoServerError: PlanExecutor error during aggregation :: caused by :: Sort exceeded memory limit of 104857600 bytes, but did not opt in to external sorting. Aborting operation.
How to fix "QueryExceededMemoryLimitNoDiskUseAllowed" in MongoDB
MissingSchemaError: Schema hasn't been registered for model
How to fix "MissingSchemaError: Schema hasn't been registered for model" in MongoDB/Mongoose
CastError: Cast to ObjectId failed for value "abc123" at path "_id"
How to fix "CastError: Cast to ObjectId failed" in MongoDB