RocketChat/Rocket.Chat · error · Meteor.Error
error-invalid-query
error-invalid-query
Error message
isValidQuery.errors.join('\n') What it means
Thrown by the users.list query path when the sanitized query fails validateQuery (the ajv-based guard that restricts allowed fields/operators). The message is the joined ajv error list, so it tells you exactly which field/operator was rejected.
Source
Thrown at apps/meteor/server/api/v1/users.ts:707
// if user provided a query, validate it with their allowed operators
// otherwise we use the default query (with $regex and $options)
if (
!isValidQuery(
nonEmptyQuery,
[
...inclusiveFieldsKeys,
inclusiveFieldsKeys.includes('emails') && 'emails.address.*',
inclusiveFieldsKeys.includes('username') && 'username.*',
inclusiveFieldsKeys.includes('name') && 'name.*',
inclusiveFieldsKeys.includes('type') && 'type.*',
inclusiveFieldsKeys.includes('customFields') && 'customFields.*',
].filter(Boolean) as string[],
// At this point, we have already validated the user query not containing malicious fields
// On here we are using our own query so we can allow some extra fields
[...this.queryOperations, '$regex', '$options'],
)
) {
throw new Meteor.Error('error-invalid-query', isValidQuery.errors.join('\n'));
}
const actualSort = sort || { username: 1 };
if (sort?.status) {
actualSort.active = sort.status;
}
if (sort?.name) {
actualSort.nameInsensitive = sort.name;
}
const limit =
count !== 0
? [
{
$limit: count,
},View on GitHub (pinned to f9d3ec372b)
Solutions
- Read the joined error text returned - it names the offending field/operator; remove or replace it.
- Restrict the query to the documented allowed fields and the allowed operator set ([queryOperations, $regex, $options]).
- URL-encode and JSON-validate the query parameter before sending.
Example fix
// before
GET /api/v1/users.list?query={ "services.google": { $exists: true } }
// after - query an allowed, indexed field
GET /api/v1/users.list?query={ "emails.address": { $regex: "@example.com", $options: "i" } } Defensive patterns
Strategy: validation
Validate before calling
// Allow-list fields and operators before sending the query
const ALLOWED_FIELDS = ['username', 'emails.address', 'name', 'type', 'status', 'roles'];
const ALLOWED_OPS = ['$eq', '$ne', '$in', '$nin', '$regex', '$options', '$exists'];
function sanitizeQuery(q: unknown): unknown {
// walk q, drop unknown keys/ops, return cleaned query or null
}
const clean = sanitizeQuery(rawQuery);
await GET(`users.list?query=${encodeURIComponent(JSON.stringify(clean))}`); Type guard
const isAllowedQuery = (q: any, allowed: string[]): boolean => q && typeof q === 'object' && Object.keys(q).every((k) => allowed.includes(k));
Try / catch
try {
await GET(`users.list?query=${encodeURIComponent(JSON.stringify(q))}`);
} catch (e) {
if (isMeteorError(e, 'error-invalid-query')) {
// e.reason contains the ajv errors; use them to fix the query
} else { throw e; }
} Prevention
- Build queries from a documented allow-list of fields/operators.
- JSON-validate and URL-encode the query parameter.
- Parse the returned ajv error text to guide the fix.
When it happens
Trigger: GET users.list?query=... with a field or MongoDB operator not in the allowed allow-list, or with a syntactically invalid query JSON.
Common situations: Client builds a query with a field the server does not expose (e.g. arbitrary services.* keys); using $where or other banned operators; malformed JSON from a query builder.
Related errors
- Cannot send system messages using 'chat.sendMessage'
- error-invalid-user
- error-invalid-date
- Invalid Api parameter provided, it must be a valid IApi obje
- The environmental variable "${envVarName}" is not readable.
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/0ff3a8034c44cd92.
Report an issue: GitHub.