Automattic/mongoose · error · TypeError

invalid argument

Error message

invalid argument

What it means

Query.prototype.near() (and nearSphere(), which sets a flag and reuses this code) accepts several one-argument forms: an array of coordinates, a path string, or an options object like {center, maxDistance}. Anything else — a number, boolean, null, or a non-plain object — hits the final else and throws a bare TypeError('invalid argument').

Source

Thrown at lib/query.js:5573

Query.prototype.near = function() {
  const params = [];
  const sphere = this._mongooseOptions.nearSphere;

  // TODO refactor

  if (arguments.length === 1) {
    if (Array.isArray(arguments[0])) {
      params.push({ center: arguments[0], spherical: sphere });
    } else if (typeof arguments[0] === 'string') {
      // just passing a path
      params.push(arguments[0]);
    } else if (utils.isObject(arguments[0])) {
      if (typeof arguments[0].spherical !== 'boolean') {
        arguments[0].spherical = sphere;
      }
      params.push(arguments[0]);
    } else {
      throw new TypeError('invalid argument');
    }
  } else if (arguments.length === 2) {
    if (typeof arguments[0] === 'number' && typeof arguments[1] === 'number') {
      params.push({ center: [arguments[0], arguments[1]], spherical: sphere });
    } else if (typeof arguments[0] === 'string' && Array.isArray(arguments[1])) {
      params.push(arguments[0]);
      params.push({ center: arguments[1], spherical: sphere });
    } else if (typeof arguments[0] === 'string' && utils.isObject(arguments[1])) {
      params.push(arguments[0]);
      if (typeof arguments[1].spherical !== 'boolean') {
        arguments[1].spherical = sphere;
      }
      params.push(arguments[1]);
    } else {
      throw new TypeError('invalid argument');
    }
  } else if (arguments.length === 3) {
    if (typeof arguments[0] === 'string' && typeof arguments[1] === 'number'

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Wrap coordinates in an array: `query.where('loc').near([1, 1])` or better `query.where('loc').near({ center: [1, 1], maxDistance: 5 })`.
  2. Parse 'lat,lng' strings into a numeric pair array before calling near().
  3. Prefer the object form { center, maxDistance, spherical } for clarity.

Example fix

// before
query.where('loc').near(req.query.coords); // '40.7,-74.0' string → TypeError: invalid argument

// after
const [lng, lat] = req.query.coords.split(',').map(Number);
query.where('loc').near({ center: [lng, lat], maxDistance: 5 });
Defensive patterns

Strategy: type-guard

Validate before calling

function nearOneArg(query, arg) {
  if (Array.isArray(arg) || typeof arg === 'string' || (arg != null && typeof arg === 'object')) {
    return query.near(arg);
  }
  throw new TypeError('near() expects an array, string, or object');
}

Type guard

const isValidNearArg = (a) => Array.isArray(a) || typeof a === 'string' || (a != null && typeof a === 'object');

Try / catch

try { query.near(input); } catch (err) { if (err instanceof TypeError && err.message === 'invalid argument') { throw new Error(`Invalid geo input for near(): ${typeof input}`); } throw err; }

Prevention

When it happens

Trigger: `query.near(5)`, `query.where('loc').near(null)`, or passing a coordinate string like `query.near('1,2')` with one argument; calling near() with a variable that is not always an array/string/object.

Common situations: Passing un-validated geo input from an API straight into near(); splitting a 'lat,lng' string but forgetting to map it to [lat, lng]; legacy code assuming older mongoose overloads like near(1, 1) are the only forms.

Related errors


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