{"record":{"id":"b79792892b99c994","repo":"Automattic/mongoose","slug":"invalid-geojson-type-for-geowithin-geowithinty","errorCode":null,"errorMessage":"Invalid geoJSON type for $geoWithin \"${geoWithinType}\", must be \"Polygon\" or \"MultiPolygon\"","messagePattern":"Invalid geoJSON type for \\$geoWithin \"(.+?)\", must be \"Polygon\" or \"MultiPolygon\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/cast.js","lineNumber":273,"sourceCode":"                  value.$minDistance,\n                  context\n                );\n              }\n              if (isMongooseObject(value.$geometry)) {\n                value.$geometry = value.$geometry.toObject({\n                  transform: false,\n                  virtuals: false\n                });\n              }\n              value = value.$geometry.coordinates;\n            } else if (geo === '$geoWithin') {\n              if (value.$geometry) {\n                if (isMongooseObject(value.$geometry)) {\n                  value.$geometry = value.$geometry.toObject({ virtuals: false });\n                }\n                const geoWithinType = value.$geometry.type;\n                if (ALLOWED_GEOWITHIN_GEOJSON_TYPES.indexOf(geoWithinType) === -1) {\n                  throw new Error('Invalid geoJSON type for $geoWithin \"' +\n                    geoWithinType + '\", must be \"Polygon\" or \"MultiPolygon\"');\n                }\n                value = value.$geometry.coordinates;\n              } else {\n                value = value.$box || value.$polygon || value.$center ||\n                  value.$centerSphere;\n                if (isMongooseObject(value)) {\n                  value = value.toObject({ virtuals: false });\n                }\n              }\n            }\n\n            _cast(value, numbertype, context);\n            continue;\n          }\n        }\n\n        if (schema.nested[path]) {","sourceCodeStart":255,"sourceCodeEnd":291,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/cast.js#L255-L291","documentation":"$geoWithin accepts a GeoJSON $geometry only when its type is 'Polygon' or 'MultiPolygon' -- a search boundary must be an area, not a point or line. lib/cast.js checks the type against an allow-list before using the coordinates and throws this Error for anything else (Point, LineString, GeometryCollection, ...).","triggerScenarios":"Model.find({ loc: { $geoWithin: { $geometry: { type: 'Point', coordinates: [lng, lat] } } } }); a type field driven by a variable that holds the queried document's type instead of the boundary's; boundary data stored as LineString.","commonSituations":"Inverting a point-in-polygon query (Point placed in $geoWithin, Polygon used as the field value); copying a $near/$geometry example where Point is correct; unvalidated GeoJSON from clients; renaming GeoJSON types during data migrations.","solutions":["Put the Polygon/MultiPolygon inside $geoWithin.$geometry and keep the Point as the queried field's value","For the inverse direction (point input, polygon field) use { loc: { $geoIntersects: { $geometry: pointGeoJSON } } }","Validate the type against ['Polygon', 'MultiPolygon'] before building the query"],"exampleFix":"// before: a Point cannot bound a $geoWithin\nModel.find({ loc: { $geoWithin: { $geometry: { type: 'Point', coordinates: [1, 1] } } } });\n\n// after: find points inside a polygon\nModel.find({ loc: { $geoWithin: { $geometry: { type: 'Polygon', coordinates: [[[0, 0], [3, 0], [3, 3], [0, 0]]] } } } });","handlingStrategy":"validation","validationCode":"const ALLOWED = ['Polygon', 'MultiPolygon'];\nfunction assertGeoWithinGeometry(clause) {\n  const geo = clause && clause.$geoWithin;\n  if (geo && geo.$geometry && !ALLOWED.includes(geo.$geometry.type)) {\n    throw new TypeError(\n      `$geoWithin type must be Polygon or MultiPolygon, got ${geo.$geometry.type}`\n    );\n  }\n}","typeGuard":"function isAreaGeometry(g) {\n  return g != null &&\n    (g.type === 'Polygon' || g.type === 'MultiPolygon') &&\n    Array.isArray(g.coordinates);\n}","tryCatchPattern":null,"preventionTips":["Remember the direction: the field holds the point, $geoWithin holds the area","Centralize GeoJSON construction in helpers that hard-code the type","Validate GeoJSON payloads (type + coordinates shape) at the API boundary"],"tags":["mongoose","geojson","geospatial","query"],"backgroundTag":"invalid-geojson-type","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}