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

  1. Use a recognized shape: { loc: { $within: { $center: [[0, 0], 5] } } }
  2. Migrate to $geoWithin -- $within is the legacy operator and modern MongoDB servers do not support it
  3. 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

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


AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21). Data as JSON: /api/errors/30eefc29816e7fbd. Report an issue: GitHub.