Automattic/mongoose · error · TypeError

Invalid `path`. Must be either string or array. Got "${path}

Error message

Invalid `path`. Must be either string or array. Got "${path}" (type ${typeof path})

What it means

TypeError from $__getValue, the internal raw getter used by $inc, populated bookkeeping and plugins: `path` must be a string or an array of keys. Any other type - number, undefined, or a plain object like a MongoDB filter passed by mistake - throws immediately with the received value and its typeof.

Source

Thrown at lib/document.js:1849

        obj = value;
      } else {
        obj = value;
      }
    }
  }
};

/**
 * Gets a raw value from a path (no getters)
 *
 * @param {string} path
 * @return {any} Returns the value from the given `path`.
 * @api private
 */

Document.prototype.$__getValue = function(path) {
  if (typeof path !== 'string' && !Array.isArray(path)) {
    throw new TypeError(
      `Invalid \`path\`. Must be either string or array. Got "${path}" (type ${typeof path})`
    );
  }
  return utils.getValue(path, this._doc);
};

/**
 * Increments the numeric value at `path` by the given `val`.
 * When you call `save()` on this document, Mongoose will send a
 * [`$inc`](https://www.mongodb.com/docs/manual/reference/operator/update/inc/)
 * as opposed to a `$set`.
 *
 * #### Example:
 *
 *     const schema = new Schema({ counter: Number });
 *     const Test = db.model('Test', schema);
 *
 *     const doc = await Test.create({ counter: 0 });

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Validate/coerce the path before the call: `if (typeof p !== 'string' && !Array.isArray(p)) return;`
  2. Use the public doc.get(path)/doc.set(path, v) API in application code
  3. Check for null/undefined earlier where the path variable is produced

Example fix

// before
doc.$__getValue(undefined); // TypeError: Invalid `path`

// after
if (typeof p !== 'string' && !Array.isArray(p)) throw new Error('path must be string or array');
const value = doc.$__getValue(p);
Defensive patterns

Strategy: type-guard

Validate before calling

// Coerce or reject before internal path APIs
if (typeof path !== 'string' && !Array.isArray(path)) {
  if (path == null) throw new Error('path is required');
  path = String(path);
}
const value = doc.$__getValue(path);

Type guard

const isValidMongoosePath = (p) => typeof p === 'string' || Array.isArray(p);

Try / catch

try {
  const v = doc.$__getValue(p);
} catch (err) {
  if (err instanceof TypeError && err.message.includes('Invalid `path`')) {
    // p was not a string/array; fix the caller that produced it
  } else { throw err; }
}

Prevention

When it happens

Trigger: Calling doc.$inc(nonString) in a configuration where the schema-type guard is bypassed; plugins or application code calling doc.$__getValue(...) with unvalidated input; path variables that are undefined because of destructuring mistakes.

Common situations: Passing a query/filter object where a path string was expected; dynamic code that builds paths and sometimes yields undefined; misuse of internal $-prefixed APIs from copied Stack Overflow snippets.

Related errors


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