MyCATApache/Mycat-Server · error · IllegalArgumentException
Both batchStartsAt and batchSize must be positive but got…
Error message
Both batchStartsAt and batchSize must be positive but got: batchStartsAt ${batchStartsAt} and batchSize ${batchSize} What it means
checkBatchSizing rejects negative batchStartsAt or batchSize values. Despite the message saying 'positive', the code only rejects values below 0; a negative offset or size would corrupt index arithmetic, so the constructor-style guard throws IllegalArgumentException immediately.
Solutions
- Clamp both parameters with Math.max(0, value) before calling.
- Fix the range computation so batchSize = end - start is non-negative (swap or validate start/end).
- Validate externally supplied indices/sizes before passing them to the ring buffer.
- Use the single-argument publishEvents(translators) overload when the whole array is intended.
Example fix
// before int size = end - start; // end < start -> negative ring.publishEvents(translators, start, size); // after int from = Math.min(start, end), to = Math.max(start, end); ring.publishEvents(translators, from, to - from);
Defensive patterns
Strategy: validation
Validate before calling
public static int safeSize(int start, int end) {
if (start < 0 || end < start) return 0;
return end - start;
}
// pass Math.max(0, batchStartsAt) and safeSize(from, to) Try / catch
try {
ring.publishEvents(translators, start, size);
} catch (IllegalArgumentException e) {
// negative offset/size: normalize and retry or skip
ring.publishEvents(translators, Math.max(0, start), Math.max(0, size));
} Prevention
- Compute batchSize as end - start only after checking start <= end
- Never pass raw user input as offset/size without clamping
- Assert non-negative start/size in debug builds
When it happens
Trigger: Calling batch publish APIs like publishEvents(translators, batchStartsAt, batchSize) or tryPublishEvents with a negative offset or negative computed size (e.g. batchStartsAt = -1, or batchSize = toIndex - fromIndex where fromIndex > toIndex).
Common situations: Reversed range variables (fromIndex > toIndex yielding a negative size), integer subtraction bugs, or unvalidated external input feeding the offset/size parameters.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- bufferSize must not be less than 1
- bufferSize must be a power of 2
- A batchSize of: with batchStatsAt of: will overrun the…
- The ring buffer cannot accommodate
- Initial capacity exceeds maximum capacity of
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/aff7865a80f167a3.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/memory/unsafe/ringbuffer/RingBuffer.java:279
}
private void checkBounds(final EventTranslator<E>[] translators, final int batchStartsAt, final int batchSize) {
checkBatchSizing(batchStartsAt, batchSize);
batchOverRuns(translators, batchStartsAt, batchSize);
}
private <A> void batchOverRuns(final A[] arg0, final int batchStartsAt, final int batchSize) {
if (batchStartsAt + batchSize > arg0.length) {
throw new IllegalArgumentException(
"A batchSize of: " + batchSize +
" with batchStatsAt of: " + batchStartsAt +
" will overrun the available number of arguments: " + (arg0.length - batchStartsAt));
}
}
private void checkBatchSizing(int batchStartsAt, int batchSize) {
if (batchStartsAt < 0 || batchSize < 0) {
throw new IllegalArgumentException("Both batchStartsAt and batchSize must be positive but got: batchStartsAt " + batchStartsAt + " and batchSize " + batchSize);
} else if (batchSize > bufferSize) {
throw new IllegalArgumentException("The ring buffer cannot accommodate " + batchSize + " it only has space for " + bufferSize + " entities.");
}
}
/**
* @see io.mycat.memory.unsafe.ringbuffer.common.event.EventSink#publishEvent(EventTranslator)
*/
@Override
public void publishEvents(EventTranslator<E>[] translators) {
publishEvents(translators, 0, translators.length);
}
private void translateAndPublishBatch(
final EventTranslator<E>[] translators, int batchStartsAt,
final int batchSize, final long finalSequence) {
final long initialSequence = finalSequence - (batchSize - 1);
try {View on GitHub (pinned to 65f8d8beb7)