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

  1. Clamp both parameters with Math.max(0, value) before calling.
  2. Fix the range computation so batchSize = end - start is non-negative (swap or validate start/end).
  3. Validate externally supplied indices/sizes before passing them to the ring buffer.
  4. 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

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


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)