{"id":"118e33fd673794a2","repo":"mongodb/node-mongodb-native","slug":"invalid-sort-direction-json-stringify-direction","errorCode":null,"errorMessage":"Invalid sort direction: ${JSON.stringify(direction)}","messagePattern":"Invalid sort direction: (.+?)","errorType":"exception","errorClass":"MongoInvalidArgumentError","httpStatus":null,"severity":"error","filePath":"src/sort.ts","lineNumber":48,"sourceCode":"\n/** @internal */\ntype SortPairForCmd = [string, SortDirectionForCmd];\n\n/** @internal */\nfunction prepareDirection(direction: any = 1): SortDirectionForCmd {\n  const value = `${direction}`.toLowerCase();\n  if (isMeta(direction)) return direction;\n  switch (value) {\n    case 'ascending':\n    case 'asc':\n    case '1':\n      return 1;\n    case 'descending':\n    case 'desc':\n    case '-1':\n      return -1;\n    default:\n      throw new MongoInvalidArgumentError(`Invalid sort direction: ${JSON.stringify(direction)}`);\n  }\n}\n\n/** @internal */\nfunction isMeta(t: SortDirection): t is { $meta: string } {\n  return typeof t === 'object' && t != null && '$meta' in t && typeof t.$meta === 'string';\n}\n\n/** @internal */\nfunction isPair(t: Sort): t is readonly [string, SortDirection] {\n  if (Array.isArray(t) && t.length === 2) {\n    try {\n      prepareDirection(t[1]);\n      return true;\n    } catch {\n      return false;\n    }\n  }","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/sort.ts#L30-L66","documentation":"Thrown by the internal prepareDirection() helper used by formatSort when a sort direction value cannot be normalized. Accepted values are 1, -1, 'asc', 'desc', 'ascending', 'descending' (case-insensitive), and { $meta: string }. Anything else, after coercion to a lowercase string, lands in the default switch branch and throws MongoInvalidArgumentError.","triggerScenarios":"Passing an invalid direction in a sort spec, e.g. { x: 'up' }, { x: 0 }, { x: 2 }, { x: true }, or a typo like { x: 'ascc' }. Also reachable via collection.find().sort('field', 'horizontal').","commonSituations":"Typos in sort direction strings; building sort specs dynamically from user input without validation; numeric values other than 1/-1; legacy code assuming 'up'/'down' work.","solutions":["Use one of the accepted literals: 1/-1 or 'asc'/'desc'.","Validate user-supplied direction against an allowlist before building the sort spec.","For text-score sorts use { $meta: 'textScore' }."],"exampleFix":"// before\nawait coll.find().sort({ score: 'up' }).toArray(); // throws\n\n// after\nawait coll.find().sort({ score: -1 }).toArray();","handlingStrategy":"validation","validationCode":"const ALLOWED = new Set([1, -1, 'asc', 'desc', 'ascending', 'descending']);\nfunction isValidDirection(d: unknown): boolean {\n  return (\n    ALLOWED.has(d as any) ||\n    (d != null && typeof d === 'object' && typeof (d as any).$meta === 'string')\n  );\n}\nif (Object.values(sortSpec).every(isValidDirection)) {\n  await coll.find().sort(sortSpec).toArray();\n}","typeGuard":"import type { SortDirection } from 'mongodb';\nfunction isSortDirection(v: unknown): v is SortDirection {\n  return [1, -1, 'asc', 'desc', 'ascending', 'descending'].includes(v as any) ||\n    (v != null && typeof v === 'object' && typeof (v as any).$meta === 'string');\n}","tryCatchPattern":"try {\n  await coll.find().sort(sortSpec).toArray();\n} catch (e) {\n  if (e instanceof MongoInvalidArgumentError && /Invalid sort direction/.test(e.message)) {\n    // coerce unknown directions to 1/-1 and retry\n  } else throw e;\n}","preventionTips":["Allowlist user-supplied sort directions before building the spec.","Prefer numeric 1/-1 over string forms to reduce typo surface.","Unit-test sort-building helpers with invalid inputs."],"tags":["sort","find","invalid-argument","query"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}