tursodatabase/turso · error · SQLException
setCharacterStream length must be non-negative
Error message
setCharacterStream length must be non-negative
What it means
Thrown by setCharacterStream(int, Reader, int) when length is negative. The driver validates the length before copying length chars from the Reader into a String: a null Reader binds SQL NULL and a zero length binds an empty string; only negative lengths throw.
Source
Thrown at bindings/java/src/main/java/tech/turso/jdbc4/JDBC4PreparedStatement.java:408
batchQueryParams.add(currentBatchParams);
currentBatchParams = new Object[paramCount];
}
@Override
public void addBatch(String sql) throws SQLException {
throw new SQLException("addBatch(String) cannot be called on a PreparedStatement");
}
@Override
public void setCharacterStream(int parameterIndex, @Nullable Reader reader, int length)
throws SQLException {
requireNonNull(this.statement);
if (reader == null) {
setParam(parameterIndex, null);
return;
}
if (length < 0) {
throw new SQLException("setCharacterStream length must be non-negative");
}
if (length == 0) {
setParam(parameterIndex, "");
return;
}
try {
char[] buffer = new char[length];
int offset = 0;
int read;
while (offset < length && (read = reader.read(buffer, offset, length - offset)) > 0) {
offset += read;
}
String value = new String(buffer, 0, offset);
setParam(parameterIndex, value);
} catch (IOException e) {
throw new SQLException("Error reading character stream", e);
}
}View on GitHub (pinned to bad083fafb)
Solutions
- Pass a non-negative char count.
- Use the no-length overload setCharacterStream(i, reader), which reads until EOF.
- To bind NULL, use setNull(i, Types.VARCHAR) or pass a null Reader.
Example fix
// before ps.setCharacterStream(1, reader, -1); // throws // after ps.setCharacterStream(1, reader); // reads until EOF
Defensive patterns
Strategy: validation
Validate before calling
if (length < 0) {
throw new IllegalArgumentException("length must be >= 0, got " + length);
}
ps.setCharacterStream(1, reader, length); Try / catch
catch (SQLException e) {
if (e.getMessage() != null && e.getMessage().contains("non-negative")) {
// fix the length argument or switch to the no-length overload
}
throw e;
} Prevention
- Use setCharacterStream(i, reader) when the char count is unknown.
- Validate char counts from external sources before binding.
- One shared helper, one length check.
When it happens
Trigger: ps.setCharacterStream(i, reader, -1); forwarding a computed char count that underflowed or defaulted to -1; using the InputStream.read() -1-equals-EOF convention where a length is expected.
Common situations: DAO layers that accept an optional length and pass -1 when unknown; counts from external systems stored in signed ints; sentinel conventions copied from other drivers.
Related errors
- setAsciiStream length must be non-negative
- setBinaryStream length must be non-negative
- Error reading ASCII stream
- setUnicodeStream length must be non-negative
- Error reading Unicode stream
AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16).
Data as JSON: /api/errors/d7741a52cb5c11bb.
Report an issue: GitHub.