{"record":{"id":"612f20b052e338f0","repo":"hibernate/hibernate-orm","slug":"length-must-be-great-than-or-equal-to-zero-612f20","errorCode":null,"errorMessage":"Length must be great-than-or-equal to zero.","messagePattern":"Length must be great-than-or-equal to zero\\.","errorType":"exception","errorClass":"SQLException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/engine/jdbc/proxy/ClobProxy.java","lineNumber":132,"sourceCode":"\tpublic Writer setCharacterStream(long pos) {\n\t\tthrow notSupported();\n\t}\n\n\t@Override\n\tpublic void truncate(long len) throws SQLException {\n\t\tthrow notSupported();\n\t}\n\n\t@Override\n\tpublic String getSubString(long start, int length) throws SQLException {\n\t\tif ( start < 1 ) {\n\t\t\tthrow new SQLException( \"Start position 1-based; must be 1 or more.\" );\n\t\t}\n\t\tif ( start > length() + 1 ) {\n\t\t\tthrow new SQLException( \"Start position [\" + start + \"] cannot exceed overall CLOB length [\" + length() + \"]\" );\n\t\t}\n\t\tif ( length < 0 ) {\n\t\t\tthrow new SQLException( \"Length must be great-than-or-equal to zero.\" );\n\t\t}\n\t\tfinal String string = characterStream.asString();\n\t\tfinal long endIndex = Math.min( start + length - 1, string.length() );\n\t\treturn string.substring( (int) start - 1, (int) endIndex );\n\t}\n\n\t@Override\n\tpublic Reader getCharacterStream(long start, long length) throws SQLException {\n\t\tif ( start < 1 ) {\n\t\t\tthrow new SQLException( \"Start position 1-based; must be 1 or more.\" );\n\t\t}\n\t\tif ( start > length() + 1 ) {\n\t\t\tthrow new SQLException( \"Start position [\" + start + \"] cannot exceed overall CLOB length [\" + length() + \"]\" );\n\t\t}\n\t\tif ( length > Integer.MAX_VALUE ) {\n\t\t\tthrow new SQLException( \"Can't deal with Clobs larger than 'Integer.MAX_VALUE'\" );\n\t\t}\n\t\tif ( length < 0 ) {","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/engine/jdbc/proxy/ClobProxy.java#L114-L150","documentation":"ClobProxy.getSubString(long start, int length) rejects a negative length with this SQLException (note the typo 'great-than-or-equal' in the Hibernate message). Zero is a legal length, but a negative count is a caller bug and fails fast before the substring is computed.","triggerScenarios":"Calling clob.getSubString(1, -1); computing length = end - start and passing it negative when end < start; forwarding a -1 from String.indexOf (not found) into getSubString.","commonSituations":"Sentinel -1 values from indexOf/lastIndexOf leaking into substring extraction; reversed or clamped index arithmetic; 'read rest' helpers with an uninitialized size.","solutions":["Pass length >= 0; use 0 to validate start without reading","Clamp computed lengths: int len = Math.max(0, end - start)","Check indexOf results for -1 before deriving lengths from them"],"exampleFix":"// before\nint idx = content.indexOf(marker);\nString s = clob.getSubString(1, idx); // idx == -1 throws\n\n// after\nint idx = content.indexOf(marker);\nString s = clob.getSubString(1, Math.max(0, idx));","handlingStrategy":"validation","validationCode":"static String safeSubString(java.sql.Clob clob, long start, int length) throws SQLException {\n    if (start < 1) throw new IllegalArgumentException(\"start must be >= 1\");\n    if (length < 0) length = 0;                     // negative means 'read nothing'\n    return clob.getSubString(start, length);\n}","typeGuard":null,"tryCatchPattern":"try {\n    s = clob.getSubString(start, length);\n} catch (SQLException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"Length must be\")) {\n        s = \"\";                                     // degrade to empty string\n    } else {\n        throw e;\n    }\n}","preventionTips":["Check indexOf results for -1 before deriving substring lengths","Clamp all length arithmetic with Math.max(0, ...)","Keep the message typo 'great-than-or-equal' in mind when matching text"],"tags":["hibernate","jdbc","clob","lob","negative-length","argument-validation","sql-exception"],"backgroundTag":"jdbc-lob-negative-length","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}