{"record":{"id":"aa0c4e9756834522","repo":"apache/beam","slug":"offset-exceeds-the-buffer-limit-offset-limit","errorCode":null,"errorMessage":"offset exceeds the buffer limit. offset: , limit: ","messagePattern":"offset exceeds the buffer limit\\. offset: , limit: ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/io/TextSource.java","lineNumber":475,"sourceCode":"  }\n\n  /**\n   * This class is created to avoid multiple bytes-copy when making a substring of the output.\n   * Without this class, it requires two bytes copies.\n   *\n   * <pre>{@code\n   * ByteArrayOutputStream out = ...;\n   * byte[] buffer = out.toByteArray(); // 1st-copy\n   * String s = new String(buffer, offset, length); // 2nd-copy\n   * }</pre>\n   */\n  static class SubstringByteArrayOutputStream extends ByteArrayOutputStream {\n    public String toString(int offset, int length, Charset charset) {\n      if (offset < 0) {\n        throw new IllegalArgumentException(\"offset is negative: \" + offset);\n      }\n      if (offset > count) {\n        throw new IllegalArgumentException(\n            \"offset exceeds the buffer limit. offset: \" + offset + \", limit: \" + count);\n      }\n\n      if (length < 0) {\n        throw new IllegalArgumentException(\"length is negative: \" + length);\n      }\n\n      if (offset + length > count) {\n        throw new IllegalArgumentException(\n            \"offset + length exceeds the buffer limit. offset: \"\n                + offset\n                + \", length: \"\n                + length\n                + \", limit: \"\n                + count);\n      }\n\n      return new String(buf, offset, length, charset);","sourceCodeStart":457,"sourceCodeEnd":493,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/io/TextSource.java#L457-L493","documentation":"SubstringByteArrayOutputStream.toString validates that the requested offset does not exceed the number of bytes actually written to the buffer (count). Throwing early with an informative message prevents the confusing StringIndexOutOfBoundsException that would otherwise come from the underlying buffer copy.","triggerScenarios":"Calling toString(offset, length, charset) where offset > count, i.e. the requested start position is past the end of bytes written so far — e.g. slicing a record using offsets from a previous buffer state after the stream was reset or truncated.","commonSituations":"TextSource record-extraction code that reuses one buffer across reads and keeps stale offsets; callers slicing at an offset computed against the original data size after buffer reuse (reset/copyFrom); tests probing boundary conditions at exactly count vs count+1.","solutions":["Check offset <= outputStream.count (or size()) before slicing; clamp or reject earlier in caller code.","Ensure the buffer is not reset/copyFrom'd between computing the offset and calling toString.","Recompute offsets from the current buffer state each read rather than caching indices from earlier reads."],"exampleFix":"// before\nString record = buffer.toString(offset, len, UTF_8);\n\n// after\nif (offset <= buffer.count) {\n  String record = buffer.toString(offset, len, UTF_8);\n} else {\n  throw new IllegalStateException(\"stale offset \" + offset + \" vs buffer size \" + buffer.count);\n}","handlingStrategy":"validation","validationCode":"checkArgument(offset <= buffer.count, \"offset %s exceeds buffer limit %s\", offset, buffer.count);","typeGuard":null,"tryCatchPattern":"try {\n  String s = buffer.toString(offset, len, UTF_8);\n} catch (IllegalArgumentException e) {\n  // recompute offsets from current buffer state and retry once\n}","preventionTips":["Recompute offsets against the live buffer each read instead of caching indices.","Avoid resetting/reusing the buffer between offset computation and slicing.","Test slicing at exactly count and count+1."],"tags":["java","apache-beam","io","argument-validation"],"backgroundTag":"argument-out-of-range","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}