{"record":{"id":"5553d21b1cf49599","repo":"elastic/elasticsearch","slug":"linear-ring-is-not-supported-by-wkt","errorCode":null,"errorMessage":"Linear ring is not supported by WKT","messagePattern":"Linear ring is not supported by WKT","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"libs/geo/src/main/java/org/elasticsearch/geometry/utils/WellKnownText.java","lineNumber":115,"sourceCode":"                    return null;\n                }\n\n                @Override\n                public Void visit(Line line) {\n                    sb.append(LPAREN);\n                    visitPoint(line.getX(0), line.getY(0), line.getZ(0));\n                    for (int i = 1; i < line.length(); ++i) {\n                        sb.append(COMMA);\n                        sb.append(SPACE);\n                        visitPoint(line.getX(i), line.getY(i), line.getZ(i));\n                    }\n                    sb.append(RPAREN);\n                    return null;\n                }\n\n                @Override\n                public Void visit(LinearRing ring) {\n                    throw new IllegalArgumentException(\"Linear ring is not supported by WKT\");\n                }\n\n                @Override\n                public Void visit(MultiLine multiLine) {\n                    visitCollection(multiLine);\n                    return null;\n                }\n\n                @Override\n                public Void visit(MultiPoint multiPoint) {\n                    if (multiPoint.isEmpty()) {\n                        sb.append(EMPTY);\n                        return null;\n                    }\n                    // walk through coordinates:\n                    sb.append(LPAREN);\n                    visitPoint(multiPoint.get(0).getX(), multiPoint.get(0).getY(), multiPoint.get(0).getZ());\n                    for (int i = 1; i < multiPoint.size(); ++i) {","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/geo/src/main/java/org/elasticsearch/geometry/utils/WellKnownText.java#L97-L133","documentation":"WellKnownText.toWKT's visitor has a visit(LinearRing) override (line 114) that unconditionally throws IllegalArgumentException. LinearRing is not a standalone WKT type — WKT has no LINEARRING keyword. A LinearRing only exists structurally inside a Polygon (whose visitor at line 185 casts its ring to Line for output). A bare LinearRing reaching the top-level toWKT visitor is a caller bug.","triggerScenarios":"Calling WellKnownText.toWKT(linearRing) where the argument is a standalone LinearRing. Constructing a Polygon manually but passing the ring (polygon.getPolygon()) to toWKT instead of the Polygon. Note: getWKTName (line 801) throws a different UnsupportedOperationException for LinearRing, so the toWKT entry path may fail earlier at naming rather than at visit.","commonSituations":"Custom geometry builders that assemble rings then serialize the ring directly. Refactoring that mis-routes a ring to the top-level serializer. Misuse of the public toWKT API with internally-typed objects. Confusing LinearRing (structural) with Line (serializable).","solutions":["Wrap the LinearRing in a Polygon before serializing: new Polygon(shell) or new Polygon(shell, holes).","Always pass the Polygon (which contains the ring) to toWKT, never a bare LinearRing.","If you have a bare ring you truly need as a linestring in text, construct a Line from the ring's coordinates and serialize that."],"exampleFix":"// before\nLinearRing shell = new LinearRing(new double[]{0,1,1,0}, new double[]{0,0,1,0});\nString wkt = WellKnownText.toWKT(shell); // throws: Linear ring is not supported by WKT\n\n// after — wrap in a Polygon\nPolygon polygon = new Polygon(shell);\nString wkt = WellKnownText.toWKT(polygon); // \"POLYGON ((0.0 0.0, 1.0 0.0, ...))\"","handlingStrategy":"type-guard","validationCode":"Geometry ensureNotBareRing(Geometry g) {\n    if (g instanceof LinearRing r) return new Polygon(r);\n    return g;\n}","typeGuard":"static boolean isBareLinearRing(Geometry g) { return g instanceof LinearRing; }","tryCatchPattern":"try {\n    return WellKnownText.toWKT(g);\n} catch (IllegalArgumentException | UnsupportedOperationException e) {\n    if (g instanceof LinearRing r) return WellKnownText.toWKT(new Polygon(r));\n    throw e;\n}","preventionTips":["Never pass a bare LinearRing to toWKT; always wrap in a Polygon first.","Add an instanceof LinearRing guard in your serialization helper.","Treat LinearRing as internal/structural; expose Polygon at API boundaries."],"tags":["geo","wkt","serialization","linear-ring","polygon","elasticsearch"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}