{"record":{"id":"245c22d9528243d9","repo":"OtterMind/Chat2DB","slug":"ewkb-linear-ring-must-contain-at-least-four-coordi","errorCode":null,"errorMessage":"EWKB linear ring must contain at least four coordinates","messagePattern":"EWKB linear ring must contain at least four coordinates","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"info","filePath":"chat2db-community-server/chat2db-community-plugins/chat2db-community-postgresql/src/main/java/ai/chat2db/plugin/postgresql/value/sub/PostgreSQLGeometryProcessor.java","lineNumber":241,"sourceCode":"            allFinite &= Double.isFinite(ordinate);\n        }\n        if (!allNaN && !allFinite) {\n            throw new IllegalArgumentException(\"EWKB point contains an invalid empty coordinate\");\n        }\n    }\n\n    private void inspectLineString(WkbCursor cursor, ByteOrder byteOrder, int coordinateDimension) {\n        int coordinateCount = readCount(cursor, byteOrder);\n        if (coordinateCount == 1) {\n            throw new IllegalArgumentException(\"EWKB line string must be empty or contain at least two coordinates\");\n        }\n        inspectFiniteCoordinates(cursor, byteOrder, coordinateCount, coordinateDimension);\n    }\n\n    private void inspectLinearRing(WkbCursor cursor, ByteOrder byteOrder, int coordinateDimension) {\n        int coordinateCount = readCount(cursor, byteOrder);\n        if (coordinateCount < 4) {\n            throw new IllegalArgumentException(\"EWKB linear ring must contain at least four coordinates\");\n        }\n\n        double[] firstCoordinate = readFiniteCoordinate(cursor, byteOrder, coordinateDimension);\n        inspectFiniteCoordinates(cursor, byteOrder, coordinateCount - 2, coordinateDimension);\n        double[] lastCoordinate = readFiniteCoordinate(cursor, byteOrder, coordinateDimension);\n        for (int i = 0; i < 2; i++) {\n            if (firstCoordinate[i] != lastCoordinate[i]) {\n                throw new IllegalArgumentException(\"EWKB linear ring is not closed\");\n            }\n        }\n    }\n\n    private void inspectFiniteCoordinates(WkbCursor cursor, ByteOrder byteOrder,\n                                          int coordinateCount, int coordinateDimension) {\n        for (int coordinate = 0; coordinate < coordinateCount; coordinate++) {\n            for (int ordinate = 0; ordinate < coordinateDimension; ordinate++) {\n                if (!Double.isFinite(cursor.readDouble(byteOrder))) {\n                    throw new IllegalArgumentException(\"EWKB coordinate is not finite\");","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/OtterMind/Chat2DB/blob/5ee1e990e73fbcae1969dc554be254fedb3ab888/chat2db-community-server/chat2db-community-plugins/chat2db-community-postgresql/src/main/java/ai/chat2db/plugin/postgresql/value/sub/PostgreSQLGeometryProcessor.java#L223-L259","documentation":"Thrown by PostgreSQLGeometryProcessor.inspectLinearRing when parsing the ring of a POLYGON in EWKB data. Per the OGC SFA specification, every linear ring (exterior or interior boundary of a polygon) must contain at least four coordinates, with the first equal to the last to close the ring. A declared count below four is structurally invalid. This runs inside convertJDBCValueByType and is caught at line 80, so the raw hex value is returned gracefully.","triggerScenarios":"Converting a PostgreSQL POLYGON geometry (baseType 3, dispatched at lines 202-207) whose EWKB declares a ring with fewer than 4 coordinates. Each ring is validated via inspectLinearRing at line 205.","commonSituations":"Corrupt polygon data; rings produced by a buggy serialization library; data migrated from a system with looser ring validation; manually crafted EWKB binary.","solutions":["No action required in production — convertJDBCValueByType catches this and returns the raw hex value","Repair the source data so every polygon ring has >=4 coordinates (including the closing point)","Use ST_MakeValid or ST_IsValidDetail in PostgreSQL to detect and reconstruct valid polygon rings"],"exampleFix":"-- before: polygon ring with only 3 points (invalid)\nSELECT ST_GeomFromEWKT('POLYGON((0 0, 1 0, 1 1))');\n-- after: polygon ring with 4 closed points\nSELECT ST_GeomFromEWKT('POLYGON((0 0, 1 0, 1 1, 0 0))');","handlingStrategy":"try-catch","validationCode":"// Already caught in convertJDBCValueByType. For direct testing:\ntry {\n    processor.convertJDBCValueByType(dataValue);\n} catch (Exception e) {\n    // raw value returned; check debug logs for details\n}","typeGuard":null,"tryCatchPattern":"try {\n    WkbHeader header = inspectEwkb(ewkb);\n} catch (IllegalArgumentException e) {\n    log.debug(\"EWKB validation failed\", e);\n    return value;\n}","preventionTips":["Ensure polygon rings have >=4 coordinates including the closing point","Use ST_IsValidDetail to find rings that are too short","Validate geometry at insert time with a CHECK constraint"],"tags":["postgresql","ewkb","geometry","polygon","validation"],"backgroundTag":null,"analyzedSha":"5ee1e990e73fbcae1969dc554be254fedb3ab888","analyzedAt":"2026-08-14T07:05:03.077Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}