{"record":{"id":"b144055e4f77504e","repo":"Automattic/mongoose","slug":"invalid-within-box-argument-expected-an-array","errorCode":null,"errorMessage":"Invalid $within $box argument. Expected an array, received ${arr}","messagePattern":"Invalid \\$within \\$box argument\\. Expected an array, received (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"lib/schema/operators/geospatial.js","lineNumber":66,"sourceCode":"      // ignore unknowns\n      break;\n  }\n\n  _castMinMaxDistance(self, val);\n\n  return val;\n}\n\nfunction cast$within(val) {\n  _castMinMaxDistance(this, val);\n\n  if (val.$box || val.$polygon) {\n    const type = val.$box ? '$box' : '$polygon';\n    val[type].forEach(arr => {\n      if (!Array.isArray(arr)) {\n        const msg = 'Invalid $within $box argument. '\n            + 'Expected an array, received ' + arr;\n        throw new TypeError(msg);\n      }\n      arr.forEach((v, i) => {\n        arr[i] = castToNumber.call(this, v);\n      });\n    });\n  } else if (val.$center || val.$centerSphere) {\n    const type = val.$center ? '$center' : '$centerSphere';\n    val[type].forEach((item, i) => {\n      if (Array.isArray(item)) {\n        item.forEach((v, j) => {\n          item[j] = castToNumber.call(this, v);\n        });\n      } else {\n        val[type][i] = castToNumber.call(this, item);\n      }\n    });\n  } else if (val.$geometry) {\n    cast$geometry(val, this);","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/schema/operators/geospatial.js#L48-L84","documentation":"When casting $within (and $geoWithin legacy shapes) with $box or $polygon, Mongoose iterates the argument and requires every entry to be an array of coordinates, which it then casts to numbers. If any entry is not an array — a flattened number, a string, an object — it throws TypeError 'Invalid $within $box argument. Expected an array, received <val>'.","triggerScenarios":"`{ loc: { $within: { $box: [0, 0, 10, 10] } } }` — coordinates flattened into four numbers instead of two points; `{ $polygon: '34,28,35,29' }` (string); `{ $box: [{ x: 0, y: 0 }, { x: 10, y: 10 }] }` (point objects instead of coordinate arrays).","commonSituations":"Flattening corner coordinates when building map-viewport queries; sending bounding boxes from client map libraries (Leaflet/Google return LatLng objects) without conversion; mixing up $box's two-point contract with $polygon's n-point polygon.","solutions":["Pass $box as exactly two coordinate arrays: `{ $box: [[x1, y1], [x2, y2]] }` (bottom-left then top-right, [lng, lat])","Pass $polygon as an array of point arrays: `{ $polygon: [[0,0],[3,6],[6,0]] }`","Convert client map bounds to arrays before querying: `[[w,s],[e,n]]`","Prefer modern $geoWithin with $geometry (`{ loc: { $geoWithin: { $geometry: { type: 'Polygon', coordinates: [...] } } } }`) — $within is a deprecated legacy operator"],"exampleFix":"// before\nModel.find({ loc: { $within: { $box: [0, 0, 10, 10] } } });\n\n// after\nModel.find({ loc: { $within: { $box: [[0, 0], [10, 10]] } } });","handlingStrategy":"validation","validationCode":"function toBoxFilter(w, s, e, n) {\n  if (![w, s, e, n].every(Number.isFinite)) throw new Error('bounds must be numbers');\n  return { $within: { $box: [[w, s], [e, n]] } }; // two points, not flattened\n}","typeGuard":"function isBoxArg(v) {\n  return Array.isArray(v) && v.length === 2 && v.every(p => Array.isArray(p) && p.every(Number.isFinite));\n}","tryCatchPattern":"try { await Model.find({ loc: { $within: { $box: box } } }); } catch (err) { if (/Invalid \\$within \\$box argument/.test(err.message)) { return badRequest('$box needs [[x1,y1],[x2,y2]]'); } throw err; }","preventionTips":["Convert map-library bounds objects to [[w,s],[e,n]] arrays server-side","Prefer $geoWithin + $geometry over legacy $within","Assert two-point shape for $box before querying"],"tags":["mongoose","geospatial","within","box","query"],"backgroundTag":"invalid-geo-query","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}