apache/seatunnel · warning

Invalid BATCH batchId in request

Error message

Invalid BATCH batchId in request: {}

What it means

Logged by dispatchBatch() when the segment before the ':' separator in a BATCH request does not parse to a positive long batch id. The server replies INVALID_PARAM and drops the request without calling the handler. This protects the batch record path from unusable identifiers.

Solutions

  1. Fix the collector to emit a positive numeric id: 'BATCH <positive-long>:<payload>'.
  2. Review the collector's batch id generation/counter for null, zero, or negative values.
  3. Use the abbreviated request in the log to confirm the exact malformed line.

Example fix

// before (client)
writer.write("BATCH " + String.valueOf(counter++) + ":" + payload); // counter started at 0
// after
long batchId = ++counter; writer.write("BATCH " + batchId + ":" + payload);
Defensive patterns

Strategy: validation

Validate before calling

if (!(Long.parseLong(idPart) > 0)) { throw new IllegalArgumentException("BATCH idPart must be a positive long: " + idPart); }

Prevention

When it happens

Trigger: A request like 'BATCH abc:payload', 'BATCH :payload', or 'BATCH -5:payload' where parseBatchId on the substring before ':' returns null or a value <= 0.

Common situations: Collector bug substituting a non-numeric placeholder for the id, off-by-one substring logic on the client, ids overflowing or being reset to 0/negative after wraparound.

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 apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/95f18f5760f17cb4. Report an issue: GitHub.

Appendix: source

Thrown at seatunnel-connectors-v2/connector-edge-socket/src/main/java/org/apache/seatunnel/connectors/seatunnel/edgesocket/protocol/IngressProtocolHandler.java:138

                    EdgeSocketLogUtils.abbreviateForLog(request));
            return EdgeSocketResponseCode.INVALID_PARAM.getCode();
        }
        return handler.handleCommitRequest(batchId);
    }

    private String dispatchBatch(String request) {
        int separatorIndex = request.indexOf(':', IngressCommand.BATCH.prefix().length());
        if (separatorIndex < 0) {
            log.warn(
                    "Malformed BATCH request, missing payload separator: {}",
                    EdgeSocketLogUtils.abbreviateForLog(request));
            return EdgeSocketResponseCode.BAD_REQUEST.getCode();
        }
        Long batchId =
                parseBatchId(request.substring(0, separatorIndex), IngressCommand.BATCH.prefix());
        if (batchId == null || batchId <= 0) {
            log.warn(
                    "Invalid BATCH batchId in request: {}",
                    EdgeSocketLogUtils.abbreviateForLog(request));
            return EdgeSocketResponseCode.INVALID_PARAM.getCode();
        }
        String payload = request.substring(separatorIndex + 1);
        return handler.handleBatchRecord(batchId, payload);
    }

    private static boolean constantTimeEquals(String expected, String actual) {
        if (expected == null || actual == null) {
            return Objects.equals(expected, actual);
        }
        byte[] a = expected.getBytes(StandardCharsets.UTF_8);
        byte[] b = actual.getBytes(StandardCharsets.UTF_8);
        return MessageDigest.isEqual(a, b);
    }

    private static String parseAuthToken(String authLine) {
        if (IngressCommand.AUTH.matches(authLine)) {

View on GitHub (pinned to cf67b549a7)