Automattic/mongoose · error · Error
Bad $within parameter: ${JSON.stringify(val)}
Error message
Bad $within parameter: ${JSON.stringify(val)} What it means
For a legacy $within geospatial query, mongoose requires the operator's value to contain one of four recognized shapes: $center, $centerSphere, $box, or $polygon. If none is present, cast() throws this Error and includes JSON.stringify of the value so the malformed shape is visible.
Source
Thrown at lib/cast.js:234
context
);
}
if (val.$minDistance != null) {
val.$minDistance = numbertype.castForQuery(
null,
val.$minDistance,
context
);
}
if (geo === '$within') {
const withinType = value.$center
|| value.$centerSphere
|| value.$box
|| value.$polygon;
if (!withinType) {
throw new Error('Bad $within parameter: ' + JSON.stringify(val));
}
value = withinType;
} else if (geo === '$near' &&
typeof value.type === 'string' && Array.isArray(value.coordinates)) {
// geojson; cast the coordinates
value = value.coordinates;
} else if ((geo === '$near' || geo === '$nearSphere' || geo === '$geoIntersects') &&
value.$geometry && typeof value.$geometry.type === 'string' &&
Array.isArray(value.$geometry.coordinates)) {
if (value.$maxDistance != null) {
value.$maxDistance = numbertype.castForQuery(
null,
value.$maxDistance,
context
);
}
if (value.$minDistance != null) {View on GitHub (pinned to 49cdab0136)
Solutions
- Use a recognized shape: { loc: { $within: { $center: [[0, 0], 5] } } }
- Migrate to $geoWithin -- $within is the legacy operator and modern MongoDB servers do not support it
- When constructing shapes programmatically, assert that one of the four $-prefixed keys exists before querying
Example fix
// before
Model.find({ loc: { $within: { center: [[0, 0], 5] } } });
// after
Model.find({ loc: { $geoWithin: { $center: [[0, 0], 5] } } }); Defensive patterns
Strategy: validation
Validate before calling
const WITHIN_SHAPES = ['$center', '$centerSphere', '$box', '$polygon'];
function hasValidWithinShape(v) {
return v != null && typeof v === 'object' &&
WITHIN_SHAPES.some(k => Object.prototype.hasOwnProperty.call(v, k));
}
const within = filter.loc && filter.loc.$within;
if (within && !hasValidWithinShape(within)) {
throw new TypeError('Bad $within parameter');
} Type guard
function isWithinQuery(v) {
return v != null && typeof v === 'object' &&
['$center', '$centerSphere', '$box', '$polygon'].some(k => k in v);
} Prevention
- Prefer $geoWithin over $within in all new code
- Build geo shapes through helper functions that always set the $-prefixed key
- Test geo queries against the same server version you run in production
When it happens
Trigger: Model.find({ loc: { $within: { $near: [...] } } }); { loc: { $within: {} } }; { loc: { $within: { center: [[0, 0], 5] } } } -- a shape key missing its $ prefix.
Common situations: Porting pre-2.4-era MongoDB code or snippets from other libraries; typos dropping the $ from shape keys; mixing $near/$geometry arguments into $within; migrations off legacy geo code where the server dropped $within support anyway.
Related errors
- Invalid geoJSON type for $geoWithin "${geoWithinType}", must
- $near must be either an array or an object with a $geometry
- Invalid $within $box argument. Expected an array, received $
- Invalid addFields() argument. Must be an object
- Query filter must be an object, got an array ${util.inspect(
AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21).
Data as JSON: /api/errors/30eefc29816e7fbd.
Report an issue: GitHub.