{"record":{"id":"92b264dcaa4b5715","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-sort","errorCode":"error-invalid-sort","errorMessage":"Invalid sort parameter provided: \"${params.sort}\"","messagePattern":"Invalid sort parameter provided: \"(.+?)\"","errorType":"validation","errorClass":"Meteor.Error","httpStatus":400,"severity":"error","filePath":"apps/meteor/server/api/lib/parseJsonQuery.ts","lineNumber":52,"sourceCode":"\n\tlet sort;\n\tif (typeof params?.sort === 'string') {\n\t\ttry {\n\t\t\tsort = JSON.parse(params.sort);\n\t\t\tObject.entries(sort).forEach(([key, value]) => {\n\t\t\t\tif (value !== 1 && value !== -1) {\n\t\t\t\t\tthrow new Meteor.Error('error-invalid-sort-parameter', `Invalid sort parameter: ${key}`, {\n\t\t\t\t\t\thelperMethod: 'parseJsonQuery',\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t} catch (e) {\n\t\t\tlogger.warn({\n\t\t\t\tmsg: 'Invalid sort parameter provided',\n\t\t\t\tsort: params.sort,\n\t\t\t\terr: e,\n\t\t\t});\n\t\t\tthrow new Meteor.Error('error-invalid-sort', `Invalid sort parameter provided: \\\"${params.sort}\\\"`, {\n\t\t\t\thelperMethod: 'parseJsonQuery',\n\t\t\t});\n\t\t}\n\t}\n\n\tconst isUnsafeQueryParamsAllowed = process.env.ALLOW_UNSAFE_QUERY_AND_FIELDS_API_PARAMS?.toUpperCase() === 'TRUE';\n\tconst messageGenerator = ({ endpoint, version, parameter }: { endpoint: string; version: string; parameter: string }): string =>\n\t\t`The usage of the \"${parameter}\" parameter in endpoint \"${endpoint}\" breaks the security of the API and can lead to data exposure. It has been deprecated and will be removed in the version ${version}.`;\n\n\tlet fields: Record<string, 0 | 1> | undefined;\n\tif (typeof params?.fields === 'string' && isUnsafeQueryParamsAllowed) {\n\t\ttry {\n\t\t\tapiDeprecationLogger.parameter(route, 'fields', '9.0.0', response, messageGenerator);\n\t\t\tfields = JSON.parse(params.fields) as Record<string, 0 | 1>;\n\t\t\tObject.entries(fields).forEach(([key, value]) => {\n\t\t\t\tif (value !== 1 && value !== 0) {\n\t\t\t\t\tthrow new Meteor.Error('error-invalid-sort-parameter', `Invalid fields parameter: ${key}`, {\n\t\t\t\t\t\thelperMethod: 'parseJsonQuery',","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/api/lib/parseJsonQuery.ts#L34-L70","documentation":"parseJsonQuery (apps/meteor/server/api/lib/parseJsonQuery.ts) runs on every list-style REST v1 endpoint and parses the sort query param with JSON.parse. Every value must be exactly the number 1 or -1; anything else throws an inner error-invalid-sort-parameter which is caught, logged as a warning, and rethrown as Meteor error-invalid-sort with the raw param in the message. Note this check is not gated by ALLOW_UNSAFE_QUERY_AND_FIELDS_API_PARAMS — the sort param is always parsed when supplied.","triggerScenarios":"Sending sort={\"ts\":\"-1\"} (string values), sort=name (bare field, not JSON), sort={\"ts\":0}/{\"ts\":2}, or any malformed JSON such as unescaped quotes in the query string. Any endpoint calling parseJsonQuery (e.g. chat.getMentionedMessages, users.list, channels.list) reproduces it.","commonSituations":"Copy-pasting Mongo shell syntax ({ts:-1} is fine but {ts:'asc'} is not); URL encoding that mangles quotes into &quot;; older clients sending 'asc'/'desc' strings; hand-built query strings concatenating sort=name directly.","solutions":["Send strict JSON with numeric values: sort={\"ts\":-1} (and URL-encode it: sort=%7B%22ts%22%3A-1%7D)","Build the param programmatically: JSON.stringify({ ts: -1 })","Drop the sort param entirely to accept the endpoint default (usually {ts: -1})"],"exampleFix":"// before\nGET /api/v1/channels.list?sort={\"name\":\"asc\"}\n\n// after\nGET /api/v1/channels.list?sort={\"name\":1}","handlingStrategy":"validation","validationCode":"type SortDir = 1 | -1;\nfunction buildSortParam(sort: Record<string, SortDir>): string {\n  for (const [k, v] of Object.entries(sort)) {\n    if (v !== 1 && v !== -1) throw new Error(`sort.${k} must be 1 or -1, got ${JSON.stringify(v)}`);\n  }\n  return JSON.stringify(sort); // e.g. '{\"ts\":-1}' — strict JSON, numeric values\n}","typeGuard":"const isSortSpec = (v: unknown): v is Record<string, 1 | -1> =>\n  typeof v === 'object' && v !== null && !Array.isArray(v) &&\n  Object.values(v).every((x) => x === 1 || x === -1);","tryCatchPattern":"try {\n  await client.get('/api/v1/channels.list', { params: { sort: JSON.stringify(sort) } });\n} catch (e: any) {\n  if (e?.response?.data?.errorType === 'error-invalid-sort') {\n    throw new ValidationError(`bad sort param: ${e.response.data.message}`);\n  }\n  throw e;\n}","preventionTips":["Never hand-write the sort param — JSON.stringify({ ts: -1 }) every time","Reject 'asc'/'desc' strings at the client boundary and map them to 1/-1","Always URL-encode JSON query params"],"tags":["rest-api","pagination","sort","validation","meteor-error"],"backgroundTag":"invalid-sort-parameter","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T10:36:37.832Z"}