{"record":{"id":"ba845743d5454c7b","repo":"tursodatabase/turso","slug":"setasciistream-length-must-be-non-negative","errorCode":null,"errorMessage":"setAsciiStream length must be non-negative","messagePattern":"setAsciiStream length must be non-negative","errorType":"exception","errorClass":"SQLException","httpStatus":null,"severity":"error","filePath":"bindings/java/src/main/java/tech/turso/jdbc4/JDBC4PreparedStatement.java","lineNumber":180,"sourceCode":"  public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {\n    requireNonNull(this.statement);\n    if (x == null) {\n      setParam(parameterIndex, null);\n    } else {\n      long time = x.getTime();\n      setParam(parameterIndex, ByteBuffer.allocate(Long.BYTES).putLong(time).array());\n    }\n  }\n\n  @Override\n  public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {\n    requireNonNull(this.statement);\n    if (x == null) {\n      setParam(parameterIndex, null);\n      return;\n    }\n    if (length < 0) {\n      throw new SQLException(\"setAsciiStream length must be non-negative\");\n    }\n    if (length == 0) {\n      setParam(parameterIndex, \"\");\n      return;\n    }\n    try {\n      byte[] buffer = new byte[length];\n      int offset = 0;\n      int read;\n      while (offset < length && (read = x.read(buffer, offset, length - offset)) > 0) {\n        offset += read;\n      }\n      String ascii = new String(buffer, 0, offset, StandardCharsets.US_ASCII);\n      setParam(parameterIndex, ascii);\n    } catch (IOException e) {\n      throw new SQLException(\"Error reading ASCII stream\", e);\n    }\n  }","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/tursodatabase/turso/blob/bad083fafbefdeae9a42ec19bdaaad8918dcf411/bindings/java/src/main/java/tech/turso/jdbc4/JDBC4PreparedStatement.java#L162-L198","documentation":"Thrown by setAsciiStream(int, InputStream, int) when the caller passes a negative length. The JDBC contract requires length to be a non-negative byte count, and this driver validates it up front, before allocating the read buffer, so a bad length is rejected at bind time without reading the stream. Note the neighboring cases: a null stream binds SQL NULL and a zero length binds an empty string; only negative lengths throw.","triggerScenarios":"Calling ps.setAsciiStream(i, in, -1); forwarding a computed length that underflowed or defaulted to -1; porting code that uses the InputStream.read() convention where -1 means 'read to EOF'.","commonSituations":"Reusable DAO layers that accept an optional length and forward -1 when the size is unknown; lengths from unsigned sources stored into a signed int; code copied from drivers where -1 meant 'unspecified'.","solutions":["Pass an exact non-negative byte count to setAsciiStream(int, InputStream, int).","If the length is unknown, call the no-length overload setAsciiStream(int, InputStream), which reads the stream until EOF.","To bind SQL NULL, pass a null stream (already handled by the driver) or use setNull(i, Types.VARCHAR) instead of a length trick."],"exampleFix":"// before\nps.setAsciiStream(1, in, -1); // throws: length must be non-negative\n\n// after\nps.setAsciiStream(1, in); // reads the stream until EOF","handlingStrategy":"validation","validationCode":"if (length < 0) {\n    throw new IllegalArgumentException(\"length must be >= 0, got \" + length);\n}\nps.setAsciiStream(1, in, length);","typeGuard":null,"tryCatchPattern":"catch (SQLException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"non-negative\")) {\n        // programmer error in the length argument — fix the caller, do not retry\n    }\n    throw e;\n}","preventionTips":["Never use -1 or Long.MAX_VALUE as an 'unknown length' sentinel with this driver; use the two-argument setAsciiStream(int, InputStream) overload.","Validate lengths coming from config or external APIs before binding.","Centralize stream binding in one helper that asserts length >= 0."],"tags":["jdbc","parameter-binding","input-validation","stream"],"backgroundTag":"jdbc-invalid-parameter-value","analyzedSha":"bad083fafbefdeae9a42ec19bdaaad8918dcf411","analyzedAt":"2026-08-16T23:12:11.798Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}