{"record":{"id":"b66a20569cb7c47c","repo":"t8y2/dbx","slug":"each-update-pipeline-stage-must-be-an-object","errorCode":null,"errorMessage":"Each update pipeline stage must be an object","messagePattern":"Each update pipeline stage must be an object","errorType":"validation","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"agents/drivers/mongodb/src/main/java/com/dbx/agent/mongodb/MongoAgent.java","lineNumber":1653,"sourceCode":"        convertMongoShellDates(doc);\n        return doc;\n    }\n\n    private static boolean isUpdatePipelineJson(String updateJson) {\n        return updateJson.trim().startsWith(\"[\");\n    }\n\n    static List<Document> updatePipelineForWrite(String updateJson) {\n        JsonElement parsed = JsonParser.parseString(updateJson);\n        if (!parsed.isJsonArray()) {\n            throw new IllegalArgumentException(\"Update pipeline must be an array\");\n        }\n        JsonArray stages = parsed.getAsJsonArray();\n        List<Document> pipeline = new ArrayList<>(stages.size());\n        for (JsonElement stage : stages) {\n            if (!stage.isJsonObject()) {\n                // The Java driver pipeline overload accepts BSON stages, not scalar array entries.\n                throw new IllegalArgumentException(\"Each update pipeline stage must be an object\");\n            }\n            pipeline.add(documentForWrite(stage.toString()));\n        }\n        return pipeline;\n    }\n\n    private static Document replacementDocument(Document doc) {\n        Document replacement = new Document(doc);\n        replacement.remove(\"_id\");\n        return replacement;\n    }\n\n    static boolean isUpdateOperatorDocument(Document doc) {\n        if (doc.isEmpty()) {\n            return false;\n        }\n        for (String key : doc.keySet()) {\n            if (!key.startsWith(\"$\")) {","sourceCodeStart":1635,"sourceCodeEnd":1671,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/mongodb/src/main/java/com/dbx/agent/mongodb/MongoAgent.java#L1635-L1671","documentation":"Within an update pipeline array, every element must be a JSON object representing one BSON stage (e.g. {\"$set\": {...}}). MongoAgent rejects scalar or array elements with this IllegalArgumentException, since the MongoDB Java driver's pipeline overload accepts BSON stage documents, not bare values.","triggerScenarios":"Sending `[{\"$set\": {...}}, \"$match\"]` or `[\"$set\"]` — a stage written as a bare string instead of `{\"$set\": ...}`; also arrays nested as stage entries.","commonSituations":"Converting shell pipelines where quoting is implicit; hand-building pipelines and forgetting the stage-object wrapper; string concatenation bugs that drop `{}` around a stage.","solutions":["Wrap each stage in an object: `[{\"$set\": {...}}, {\"$unset\": [\"oldField\"]}]`.","Replace bare operator strings like `\"$set\"` with `{\"$set\": {\"field\": value}}`.","Validate each element with `element.isJsonObject()` (Gson) before sending.","Re-serialize the pipeline from typed objects instead of string concatenation."],"exampleFix":"// before\n{\"updateOne\": {\"filter\": {\"_id\": 1}, \"update\": [\"$set\", {\"a\": 1}]}}\n// after\n{\"updateOne\": {\"filter\": {\"_id\": 1}, \"update\": [{\"$set\": {\"a\": 1}}]}}","handlingStrategy":"validation","validationCode":"// Java (Gson): every stage must be an object\ncom.google.gson.JsonArray stages = com.google.gson.JsonParser.parseString(updateJson).getAsJsonArray();\nfor (com.google.gson.JsonElement stage : stages) {\n    if (!stage.isJsonObject())\n        throw new IllegalArgumentException(\"Each update pipeline stage must be an object\");\n}","typeGuard":"static boolean isStageObject(com.google.gson.JsonElement e) { return e != null && e.isJsonObject() && e.getAsJsonObject().keySet().stream().allMatch(k -> k.startsWith(\"$\")); }","tryCatchPattern":"try { agent.updateOne(filter, updateJson); }\ncatch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"pipeline stage must be an object\")) {\n    // fix the offending stage to {\"$op\": {...}} and retry\n  } else throw e;\n}","preventionTips":["Always wrap stages as {\"$set\": {...}}, never bare \"$set\" strings","Build pipelines from typed objects and serialize once","Lint pipeline JSON for stage keys starting with '$'"],"tags":["mongodb","validation","update-pipeline","json"],"backgroundTag":"invalid-argument-type","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}