django/django · error · TypeError
Cannot set %s SpatialProxy (%s) with value of type: %s
Error message
Cannot set %s SpatialProxy (%s) with value of type: %s
What it means
Raised as TypeError by SpatialProxy.__set__ (the descriptor for GeometryField/RasterField) when assigning a value whose type does not match any accepted form. For raster fields only None/str/dict/raster instances are accepted; for geometry fields None/str/memoryview/GEOSGeometry instances are accepted; everything else is rejected at proxy.py:82.
Source
Thrown at django/contrib/gis/db/models/proxy.py:82
gtype = self.field.geom_type
if gtype == "RASTER" and (
value is None or isinstance(value, (str, dict, self._klass))
):
# For raster fields, ensure input is None or a string, dict, or
# raster instance.
pass
elif isinstance(value, self._klass):
# The geometry type must match that of the field -- unless the
# general GeometryField is used.
if value.srid is None:
# Assigning the field SRID if the geometry has no SRID.
value.srid = self.field.srid
elif value is None or isinstance(value, (str, memoryview)):
# Set geometries with None, WKT, HEX, or WKB
pass
else:
raise TypeError(
"Cannot set %s SpatialProxy (%s) with value of type: %s"
% (instance.__class__.__name__, gtype, type(value))
)
# Setting the object's dictionary with the value, and returning.
instance.__dict__[self.field.attname] = value
return value
View on GitHub (pinned to ae25a40be0)
Solutions
- Convert the value: GEOSGeometry(wkt_or_hexewkb) for geometries, memoryview(wkb) for raw WKB, or GDALRaster(dict) for rasters.
- Pass None to clear the field.
- For shapely or geojson-py objects, serialize to WKT/GeoJSON first and wrap in GEOSGeometry.
Example fix
// before obj.geom = shapely_geom // after from django.contrib.gis.geos import GEOSGeometry obj.geom = GEOSGeometry(shapely_geom.wkt)
Defensive patterns
Strategy: type-guard
Validate before calling
from django.contrib.gis.geos import GEOSGeometry
from django.contrib.gis.gdal import GDALRaster
def coerce_geom_value(field, value):
if field.geom_type == 'RASTER':
if value is None or isinstance(value, (str, dict, GDALRaster)):
return value
elif value is None or isinstance(value, (str, memoryview, GEOSGeometry)):
return value
raise TypeError(f'Unsupported value type for {field.attname}: {type(value)}') Type guard
def is_assignable_to_field(field, value):
if field.geom_type == 'RASTER':
return value is None or isinstance(value, (str, dict, GDALRaster))
return value is None or isinstance(value, (str, memoryview, GEOSGeometry)) Try / catch
try:
obj.geom = incoming
except TypeError as e:
if 'SpatialProxy' in str(e):
obj.geom = GEOSGeometry(incoming.wkt) if hasattr(incoming, 'wkt') else None Prevention
- Always wrap foreign geometry types (shapely, geojson) in GEOSGeometry before assignment.
- Use memoryview for raw WKB rather than bytes.
When it happens
Trigger: instance.geom = 12345, instance.geom = ['POINT(0 0)'], or instance.raster = b'\x89PNG...' (bytes) for a raster field. The descriptor checks isinstance against the field class and the whitelisted scalar types.
Common situations: Assigning raw WKB bytes (should be memoryview), a list/dict for a geometry field (raster-only), an int ID, or a shape from another library (shapely) that is not a GEOSGeometry.
Related errors
- Invalid data source input type: %s
- Input to 'set_3d' must be a boolean, got '{value!r}'.
- Input to 'set_measured' must be a boolean, got '{value!r}'.
- Cannot assign spatial reference with object of type: %s
- SRID must be set with an integer.
AI-assisted analysis of django/django@ae25a40be0 (2026-08-06).
Data as JSON: /api/errors/0f908d300a9da3d6.
Report an issue: GitHub.