t8y2/dbx · error · IllegalStateException
unknown geometry kind: <kind>
Error message
unknown geometry kind: <kind>
What it means
EwkbWktDecoder.geometryToWkt() switches over the GeomKind enum and its default branch throws IllegalStateException("unknown geometry kind: ...") as a defensive guard. It fires when a Geometry instance carries a GeomKind value the formatter has no case for — normally impossible for decoded EWKB, and indicates the enum was extended with a new kind without updating geometryToWkt, or a Geometry was constructed programmatically with an invalid kind.
Source
Thrown at agents/common/src/main/java/com/dbx/agent/EwkbWktDecoder.java:534
return "MULTILINESTRING" + suffix + "(" + joinRings(g.rings) + ")";
case MULTIPOLYGON:
if (g.polygons == null || g.polygons.isEmpty()) {
return "MULTIPOLYGON" + suffix + " EMPTY";
}
return "MULTIPOLYGON" + suffix + "(" + joinPolygons(g.polygons) + ")";
case GEOMETRYCOLLECTION:
if (g.children == null || g.children.isEmpty()) {
return "GEOMETRYCOLLECTION" + suffix + " EMPTY";
}
StringBuilder sb = new StringBuilder("GEOMETRYCOLLECTION").append(suffix).append("(");
for (int i = 0; i < g.children.size(); i++) {
if (i > 0) sb.append(',');
sb.append(geometryToWkt(g.children.get(i)));
}
sb.append(')');
return sb.toString();
default:
throw new IllegalStateException("unknown geometry kind: " + g.kind);
}
}
private static String formatCoord(List<Double> coords) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < coords.size(); i++) {
if (i > 0) sb.append(' ');
sb.append(formatDouble(coords.get(i)));
}
return sb.toString();
}
private static String formatCoordSeq(List<List<Double>> points) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < points.size(); i++) {
if (i > 0) sb.append(',');
sb.append(formatCoord(points.get(i)));
}View on GitHub (pinned to c0390bff16)
Solutions
- Add a case for the reported kind string to geometryToWkt's switch so the new geometry type is formatted.
- If kind is null, trace where the Geometry was constructed and pass a valid GeomKind from the decoded EWKB type byte.
- Check versions: ensure the EWKB decoding path and the WKT formatting switch come from the same build (rebuild after enum changes).
- For valid-but-unformattable kinds, decode with a fallback that returns the hex representation instead of WKT.
Example fix
// before
default:
throw new IllegalStateException("unknown geometry kind: " + g.kind);
// after
case TRIANGLE:
sb.append("TRIANGLE(")...;
return sb.toString();
default:
throw new IllegalStateException("unknown geometry kind: " + g.kind); Defensive patterns
Strategy: try-catch
Validate before calling
if (g == null || g.kind == null) { return fallbackHex; } // validate before formatting Type guard
static boolean hasKnownKind(EwkbWktDecoder.Geometry g) {
return g != null && g.kind != null;
} Try / catch
try {
return geometryToWkt(g);
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("unknown geometry kind")) {
return originalHex; // fall back to raw EWKB hex
}
throw e;
} Prevention
- When adding a GeomKind constant, update every switch over kind (compiler-exhaustive switch without default helps).
- Only construct Geometry objects via the decoder, never by hand.
- Round-trip test: decode EWKB then format WKT for every supported geometry type.
- Keep decode and format code in the same module/version to avoid enum drift.
When it happens
Trigger: A GeomKind enum constant was added (e.g. a new geometry type like GEOMETRYCOLLECTION variant) but the switch in geometryToWkt was not updated; a Geometry object built outside decodeToWkt/decode paths has a null or out-of-range kind; kind is null and the switch has no null case.
Common situations: Upgrading the decoder library or adding new EWKB geometry types and hitting the guard while converting to WKT; custom code constructing Geometry records directly with a kind the formatter doesn't know.
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/81779eb332d0f65c.
Report an issue: GitHub.