dgraph-io/dgraph · error
Expected a Geo type
Error message
Expected a Geo type
What it means
types.Marshal raises this when the source Val claims Tid GeoID but its Value does not implement geom.T (the Go geom library geometry interface). Marshal type-asserts val.(geom.T) and this assertion failed, so the value is not actually a geometry object (point/polygon etc.).
Source
Thrown at types/conversion.go:592
case StringID, DefaultID:
val, err := vc.MarshalText()
if err != nil {
return err
}
*res = string(val)
case BinaryID:
r, err := vc.MarshalBinary()
if err != nil {
return err
}
*res = r
default:
return cantConvert(fromID, toID)
}
case GeoID:
vc, ok := val.(geom.T)
if !ok {
return errors.Errorf("Expected a Geo type")
}
switch toID {
case BinaryID:
r, err := wkb.Marshal(vc, binary.LittleEndian)
if err != nil {
return err
}
*res = r
case StringID, DefaultID:
val, err := geojson.Marshal(vc)
if err != nil {
return nil
}
*res = string(bytes.Replace(val, []byte("\""), []byte("'"), -1))
default:
return cantConvert(fromID, toID)
}
case PasswordID:View on GitHub (pinned to 759e242be6)
Solutions
- Parse the textual geo value first with types.ParseValue into a Val whose Value is a geom.T, then Marshal it
- Ensure the Value is a concrete geom type, e.g. orb/geom.Point or geom.Polygon, when setting Tid: types.GeoID
- Check upstream code paths that construct geo Vals and add the missing parse/conversion step
Example fix
// before
types.Marshal(types.Val{Tid: types.GeoID, Value: `POINT(1 2)`}, out) // string, not geom.T
// after
var parsed types.Val
if err := types.ParseValue(types.GeoID, []byte(`POINT(1 2)`), &parsed); err == nil {
err = types.Marshal(parsed, out)
} Defensive patterns
Strategy: type-guard
Validate before calling
func isGeomVal(v types.Val) bool {
_, ok := v.Value.(geom.T)
return v.Tid == types.GeoID && ok
}
if isGeomVal(v) { types.Marshal(v, out) } else { /* parse via types.ParseValue first */ } Type guard
func toGeoVal(raw string) (types.Val, error) {
var out types.Val
err := types.ParseValue(types.GeoID, []byte(raw), &out)
return out, err // out.Value is guaranteed to be a geom.T on success
} Prevention
- Never put raw WKT/GeoJSON strings in a Val with Tid GeoID
- Always parse geo literals with types.ParseValue before marshaling
- Keep geo values as geom.T types end to end
When it happens
Trigger: types.Marshal with from.Tid == GeoID and Value being a string, []byte, or other non-geom.T type — e.g. a WKT string placed directly in the Val instead of being parsed first.
Common situations: Building Val structs manually with GeoID but raw WKT text; passing GeoJSON strings without parsing; refactors that lost the types.ParseValue/parsing step.
Related errors
- invalid conversion %s to nil
- while processing '%s', brackets are not closed properly
- error while trying to parse value: %+v as geo val
- couldn't convert value: %s to geo type
- Leaf predicate:'%v' must be a scalar.
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/9f0134bb16614521.
Report an issue: GitHub.