{"record":{"id":"bd22518e57c7e218","repo":"t8y2/dbx","slug":"offsets-must-be-an-array","errorCode":null,"errorMessage":"offsets must be an array","messagePattern":"offsets must be an array","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"agents/drivers/kafka/src/main/java/com/dbx/agent/kafka/KafkaAgent.java","lineNumber":1517,"sourceCode":"                for (Map.Entry<TopicPartition, ListOffsetsResult.ListOffsetsResultInfo> entry : latest.entrySet()) {\n                    offsets.put(entry.getKey(), new OffsetAndMetadata(entry.getValue().offset()));\n                }\n            }\n        }\n\n        admin.alterConsumerGroupOffsets(groupId, offsets)\n            .all().get(timeout, TimeUnit.MILLISECONDS);\n        return Collections.singletonMap(\"ok\", true);\n    }\n\n    static Map<TopicPartition, OffsetAndMetadata> explicitConsumerGroupOffsets(JsonObject params, String topic) {\n        Map<TopicPartition, OffsetAndMetadata> offsets = new HashMap<>();\n        if (!params.has(\"offsets\")) {\n            return offsets;\n        }\n        JsonElement offsetsElement = params.get(\"offsets\");\n        if (!offsetsElement.isJsonArray()) {\n            throw new IllegalArgumentException(\"offsets must be an array\");\n        }\n        JsonArray offsetArray = offsetsElement.getAsJsonArray();\n        if (offsetArray.isEmpty()) {\n            throw new IllegalArgumentException(\"offsets must contain at least one partition offset\");\n        }\n        for (JsonElement element : offsetArray) {\n            if (!element.isJsonObject()) {\n                throw new IllegalArgumentException(\"each offset must be an object\");\n            }\n            JsonObject value = element.getAsJsonObject();\n            int partition = nonNegativeExactInt(value, \"partition\");\n            long offset = nonNegativeExactLong(value, \"offset\");\n            TopicPartition topicPartition = new TopicPartition(topic, partition);\n            if (offsets.put(topicPartition, new OffsetAndMetadata(offset)) != null) {\n                throw new IllegalArgumentException(\"duplicate partition in offsets: \" + partition);\n            }\n        }\n        return offsets;","sourceCodeStart":1499,"sourceCodeEnd":1535,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/kafka/src/main/java/com/dbx/agent/kafka/KafkaAgent.java#L1499-L1535","documentation":"When committing consumer offsets, the agent reads an offsets parameter from the request's JSON params and requires it to be a JSON array of per-partition offset entries. If the offsets key is present but its value is not a JSON array, the agent throws IllegalArgumentException with this message. It is an input-validation error protecting the downstream deserialization loop that iterates the array.","triggerScenarios":"Calling the agent's commit-offsets operation with a params object where \"offsets\" exists but holds a JSON object, string, number, or null instead of an array, e.g. {\"offsets\": {\"topic\": \"t\", \"partition\": 0, \"offset\": 42}}.","commonSituations":"Client serializing a single offset as an object instead of wrapping it in an array; a schema/API version mismatch where an older client sends a map-shaped offsets payload; hand-written tooling or scripts constructing the request JSON with the wrong shape.","solutions":["Send offsets as a JSON array of partition-offset entries, e.g. \"offsets\": [{\"topic\":\"t\",\"partition\":0,\"offset\":42,\"metadata\":\"\"}].","Fix the client serializer so a single offset is wrapped in a one-element array.","Validate the payload shape before sending (JSON schema or a client-side check that offsets is an array).","Check client/agent API version compatibility if an older format (object/map) was previously accepted."],"exampleFix":"// before\n{\"offsets\": {\"topic\": \"events\", \"partition\": 0, \"offset\": 42}}\n// after\n{\"offsets\": [{\"topic\": \"events\", \"partition\": 0, \"offset\": 42}]}","handlingStrategy":"validation","validationCode":"if (!params.has(\"offsets\") || !params.get(\"offsets\").isJsonArray()) {\n    throw new IllegalArgumentException(\"offsets must be a non-null JSON array\");\n}","typeGuard":"boolean validOffsetsParam(JsonObject params) {\n    return params.has(\"offsets\") && params.get(\"offsets\").isJsonArray()\n        && !params.getAsJsonArray(\"offsets\").isEmpty();\n}","tryCatchPattern":"try {\n    agent.commitOffsets(params);\n} catch (IllegalArgumentException e) {\n    if (String.valueOf(e.getMessage()).contains(\"offsets must be\")) {\n        // log payload shape and reject/fix client request\n    } else throw e;\n}","preventionTips":["Document and enforce the offsets payload schema (array of {topic, partition, offset}) client-side.","Always wrap a single offset in an array before serializing.","Add JSON schema validation at the API boundary to catch malformed payloads before they reach the agent.","Version the request format when clients may send legacy map-shaped offsets."],"tags":["kafka","validation","input-format","json"],"backgroundTag":"invalid-json-payload","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}