Automattic/mongoose · error · MongooseError
Invalid field "" passed to sort()
Error message
Invalid field "" passed to sort()
What it means
Before executing, Mongoose inspects query.options.sort and rejects an object that owns an empty-string key (sort({ '': 1 })). Sorting on an empty field name is meaningless and usually the result of building a sort object dynamically, so the check catches it client-side with a clear message.
Source
Thrown at lib/query.js:4767
this._validateOp();
if (typeof op === 'string') {
this.op = op;
}
if (this.op == null) {
throw new MongooseError('Query must have `op` before executing');
}
if (this.model == null) {
throw new MongooseError('Query must have an associated model before executing');
}
const thunk = opToThunk.get(this.op);
if (!thunk) {
throw new MongooseError('Query has invalid `op`: "' + this.op + '"');
}
if (this.options?.sort && typeof this.options.sort === 'object' && Object.hasOwn(this.options.sort, '')) {
throw new MongooseError('Invalid field "" passed to sort()');
}
if (this._execCount > 0) {
let str = this.toString();
if (str.length > 60) {
str = str.slice(0, 60) + '...';
}
throw new MongooseError('Query was already executed: ' + str);
}
this._execCount++;
const _this = this;
return traceQuery(async function maybeTracedQueryExec() {
let skipWrappedFunction = null;
try {
await _this._hooks.execPre('exec', _this, []);
} catch (err) {
if (err instanceof Kareem.skipWrappedFunction) {View on GitHub (pinned to 49cdab0136)
Solutions
- Validate/normalize user-supplied sort fields and skip empties: `if (field) sort[field] = dir;`.
- Default to a real field or no sort at all when the input is empty.
- Add allowlist checks so only known schema fields reach sort().
Example fix
// before
const sort = { [req.query.sortBy]: 1 }; // req.query.sortBy === '' → Invalid field "" passed to sort()
await Model.find().sort(sort).exec();
// after
const allowed = ['name', 'createdAt', 'price'];
const sortBy = allowed.includes(req.query.sortBy) ? req.query.sortBy : 'createdAt';
await Model.find().sort({ [sortBy]: 1 }).exec(); Defensive patterns
Strategy: validation
Validate before calling
function buildSort(sortBy, dir = 1, allowed = ['name','createdAt','price']) {
if (!sortBy || !allowed.includes(sortBy)) return {};
return { [sortBy]: dir };
} Type guard
const hasEmptySortKey = (sort) => sort != null && typeof sort === 'object' && Object.hasOwn(sort, '');
Try / catch
try { await Model.find().sort(sort).exec(); } catch (err) { if (err instanceof mongoose.Error && /Invalid field ""/.test(err.message)) { delete sort['']; return Model.find().sort(sort).exec(); } throw err; } Prevention
- Allowlist user-supplied sort fields against schema paths.
- Skip empty sort keys instead of defaulting them to ''.
- Trim and validate dynamic field names before building sort objects.
When it happens
Trigger: `query.sort({ '': 1 })`; `query.sort('')` or `query.sort('name ')` trimmed to an empty field; sort objects built as `{ [req.query.sortField]: 1 }` when sortField is '' or undefined-coerced; CSV/env-driven sort fields that arrive empty.
Common situations: Exposing a sort parameter from an HTTP query string or config without validating it; defaulting sort keys to '' instead of skipping; string parsing that splits on a delimiter and yields empty tokens.
Related errors
- sort() takes at most 2 arguments
- sort() options argument must be an object or nullish
- Invalid sort() argument, must be array of arrays
- Invalid sort() argument. Must be a string, object, array, or
- Invalid sort value: { ${key}: ${val} }
AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21).
Data as JSON: /api/errors/7a818e9bf5847942.
Report an issue: GitHub.