{"record":{"id":"4a4a59d841ad3912","repo":"t8y2/dbx","slug":"failed-to-read-clob-value","errorCode":null,"errorMessage":"Failed to read CLOB value","messagePattern":"Failed to read CLOB value","errorType":"exception","errorClass":"SQLException","httpStatus":null,"severity":"error","filePath":"plugins/jdbc/src/main/java/app/dbx/jdbc/DbxJdbcPlugin.java","lineNumber":4335,"sourceCode":"            return decimal;\n        }\n        if (value instanceof Number || value instanceof Boolean || value instanceof String) {\n            return value;\n        }\n        return value.toString();\n    }\n\n    private static String clobToString(Clob clob) throws SQLException {\n        try (Reader reader = clob.getCharacterStream()) {\n            StringBuilder out = new StringBuilder();\n            char[] buffer = new char[8192];\n            int count;\n            while ((count = reader.read(buffer)) != -1) {\n                out.append(buffer, 0, count);\n            }\n            return out.toString();\n        } catch (IOException error) {\n            throw new SQLException(\"Failed to read CLOB value\", error);\n        }\n    }\n\n    private static Object readTemporalValue(\n        ResultSet rs,\n        ResultSetMetaData meta,\n        int index,\n        boolean preserveOracleDateTime,\n        ZoneId timestampZone\n    ) throws SQLException {\n        return switch (meta.getColumnType(index)) {\n            case Types.DATE -> {\n                if (preserveOracleDateTime) {\n                    Timestamp timestamp = rs.getTimestamp(index);\n                    yield timestamp == null ? null : timestamp.toString();\n                }\n                Date date = rs.getDate(index);\n                yield date == null ? null : date.toString();","sourceCodeStart":4317,"sourceCodeEnd":4353,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/plugins/jdbc/src/main/java/app/dbx/jdbc/DbxJdbcPlugin.java#L4317-L4353","documentation":"When reading a ResultSet value that is a Clob, the plugin streams it into a String; any IOException raised by Clob.getCharacterStream() is wrapped in a SQLException with message \"Failed to read CLOB value\" and the original cause attached. This indicates the large-character data could not be read from the driver, often after the connection/statement state was invalidated.","triggerScenarios":"Calling nextRow/fetch on a result set containing CLOB/TEXT columns when the underlying stream fails — e.g. connection dropped mid-read, driver freed the LOB after the row cursor moved, or an encoding/stream error in the JDBC driver.","commonSituations":"Network interruption while streaming a large text column; drivers that invalidate LOBs once ResultSet.next() advances; fetching very large CLOBs that exceed driver memory/stream limits; connection timeout during read.","solutions":["Check the wrapped cause (error.getCause()) to identify the driver-level failure","Re-run the query and read the row again (transient network issues)","Reduce the number/size of CLOB columns fetched or paginate the query","Ensure the CLOB is fully consumed before advancing the ResultSet; upgrade/patch the JDBC driver","Increase connection/socket timeouts for large text columns"],"exampleFix":"// before\nrs.next(); String a = rs.getString(1); String clobText = pluginReadClob(rs.getClob(2)); // LOB freed by some drivers after next()\n// after\nrs.next(); String clobText = pluginReadClob(rs.getClob(2)); String a = rs.getString(1); // read CLOB before moving on","handlingStrategy":"retry","validationCode":"// Before reading, verify the LOB is live and the connection is open:\nif (clob == null) return null;\nif (connection.isClosed() || rs.isClosed()) {\n    throw new IllegalStateException(\"Connection/ResultSet closed before CLOB read\");\n}","typeGuard":"boolean isReadable(Clob clob) {\n    try { return clob != null && clob.length() >= 0; } catch (SQLException e) { return false; }\n}","tryCatchPattern":"try {\n    return readClob(rs.getClob(col));\n} catch (SQLException e) {\n    if (e.getMessage().startsWith(\"Failed to read CLOB value\")) {\n        // re-execute query and retry once; log e.getCause() for the driver-level reason\n    } else throw e;\n}","preventionTips":["Read CLOB values before advancing ResultSet.next()","Consume LOBs fully while the connection/statement is still open","Increase socket/connection timeouts for large text columns","Log e.getCause() to identify the underlying driver/stream error","Upgrade the JDBC driver if LOBs are invalidated prematurely"],"tags":["jdbc","clob","io"],"backgroundTag":"lob-read-failed","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}