t8y2/dbx · error · IllegalArgumentException

each offset must be an object

Error message

each offset must be an object

What it means

Each element of the "offsets" array must be a JSON object describing one partition offset. The parser iterates the array and throws IllegalArgumentException as soon as an element is not an object (KafkaAgent.java:1525).

Source

Thrown at agents/drivers/kafka/src/main/java/com/dbx/agent/kafka/KafkaAgent.java:1525

        return Collections.singletonMap("ok", true);
    }

    static Map<TopicPartition, OffsetAndMetadata> explicitConsumerGroupOffsets(JsonObject params, String topic) {
        Map<TopicPartition, OffsetAndMetadata> offsets = new HashMap<>();
        if (!params.has("offsets")) {
            return offsets;
        }
        JsonElement offsetsElement = params.get("offsets");
        if (!offsetsElement.isJsonArray()) {
            throw new IllegalArgumentException("offsets must be an array");
        }
        JsonArray offsetArray = offsetsElement.getAsJsonArray();
        if (offsetArray.isEmpty()) {
            throw new IllegalArgumentException("offsets must contain at least one partition offset");
        }
        for (JsonElement element : offsetArray) {
            if (!element.isJsonObject()) {
                throw new IllegalArgumentException("each offset must be an object");
            }
            JsonObject value = element.getAsJsonObject();
            int partition = nonNegativeExactInt(value, "partition");
            long offset = nonNegativeExactLong(value, "offset");
            TopicPartition topicPartition = new TopicPartition(topic, partition);
            if (offsets.put(topicPartition, new OffsetAndMetadata(offset)) != null) {
                throw new IllegalArgumentException("duplicate partition in offsets: " + partition);
            }
        }
        return offsets;
    }

    private static int nonNegativeExactInt(JsonObject object, String name) {
        long value = nonNegativeExactLong(object, name);
        if (value > Integer.MAX_VALUE) {
            throw new IllegalArgumentException(name + " is outside the supported integer range");
        }
        return (int) value;

View on GitHub (pinned to c0390bff16)

Solutions

  1. Wrap each offset entry as an object: {"partition": <int>, "offset": <long>}
  2. Verify the JSON serialization step is not flattening objects into scalars
  3. Validate the array client-side before sending (every element is a JSON object)

Example fix

// before
{"offsets": [0, 1]}
// after
{"offsets": [{"partition": 0, "offset": 100}, {"partition": 1, "offset": 200}]}
Defensive patterns

Strategy: validation

Validate before calling

const ok = Array.isArray(offsets) && offsets.every(o => o !== null && typeof o === 'object' && !Array.isArray(o));

Type guard

function isOffsetEntry(o) { return typeof o === 'object' && o !== null && !Array.isArray(o) && Number.isInteger(o.partition) && Number.isInteger(o.offset) && o.partition >= 0 && o.offset >= 0; }

Try / catch

try { agent.execute(req); } catch (e) { if (String(e.message).includes('each offset must be an object')) { /* inspect offsets elements */ } else throw e; }

Prevention

When it happens

Trigger: Passing offsets like [1], ["0"], [null], or [[0,100]] where array items are numbers/strings/nulls/nested arrays instead of objects with partition/offset fields.

Common situations: Hand-written JSON payloads missing braces; serializing a Map.Entry or tuple directly instead of a structured object; double-encoding offsets as strings.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/0709700d1eef1e49. Report an issue: GitHub.