t8y2/dbx · error · java.lang.IllegalArgumentException

Each MongoDB insertMany document must be an object

Error message

Each MongoDB insertMany document must be an object

What it means

insertMany validated that docs_json is an array, but at least one element of that array is not a JSON object. Every element must be a document (JSON object) that can be converted via documentForWrite; scalars or nested arrays are rejected.

Source

Thrown at agents/drivers/mongodb/src/main/java/com/dbx/agent/mongodb/MongoAgent.java:1480

        String docJson = params.get("doc_json").getAsString();

        Document doc = Document.parse(docJson);
        c.getDatabase(database).getCollection(collection).insertOne(doc);
        Object insertedId = convertValue(doc.get("_id"));
        return Collections.singletonMap("inserted_id", insertedId);
    }

    private static Object insertDocuments(JsonObject params) {
        String docsJson = params.get("docs_json").getAsString();
        JsonElement parsed = JsonParser.parseString(docsJson);
        if (!parsed.isJsonArray()) {
            throw new IllegalArgumentException("MongoDB insertMany documents must be a JSON array");
        }

        List<Document> documents = new ArrayList<>();
        for (JsonElement item : parsed.getAsJsonArray()) {
            if (!item.isJsonObject()) {
                throw new IllegalArgumentException("Each MongoDB insertMany document must be an object");
            }
            documents.add(documentForWrite(item.toString()));
        }
        if (documents.isEmpty()) {
            return Collections.singletonMap("affected_rows", 0);
        }

        MongoClient client = requireClient();
        String database = params.get("database").getAsString();
        String collection = params.get("collection").getAsString();
        client.getDatabase(database).getCollection(collection).insertMany(documents);
        return Collections.singletonMap("affected_rows", documents.size());
    }

    static Object parseId(String id) {
        String stringId = decodeStringDocumentId(id);
        if (stringId != null) {
            return stringId;

View on GitHub (pinned to c0390bff16)

Solutions

  1. Make every element a JSON object: [{...}, {...}]
  2. If you have pre-serialized document strings, parse each into an object before building the array
  3. Validate array elements are objects before calling insertMany

Example fix

// before
agent.insertMany(coll, "[{\"name\":\"a\"}, \"{\\\"name\\\":\\\"b\\\"}\"]");
// after
agent.insertMany(coll, "[{\"name\":\"a\"}, {\"name\":\"b\"}]");
Defensive patterns

Strategy: validation

Validate before calling

const docs = JSON.parse(docsJson);
const bad = docs.findIndex(d => d === null || typeof d !== 'object' || Array.isArray(d));
if (bad !== -1) throw new Error(`docsJson[${bad}] is not an object`);

Type guard

const isPlainObject = (d) =>
  d !== null && typeof d === 'object' && !Array.isArray(d);

Try / catch

try {
  agent.insertMany(coll, docsJson);
} catch (IllegalArgumentException e) {
  if (e.getMessage().includes("document must be an object")) {
    const fixed = JSON.parse(docsJson).map(parseIfStringDoc).filter(isPlainObject);
    agent.insertMany(coll, JSON.stringify(fixed));
  } else throw e;
}

Prevention

When it happens

Trigger: Calling insertMany with '["doc1", "doc2"]' (strings instead of objects), '[{"name":"a"}, [1,2]]', or '[null]'. The loop throws on the first element where item.isJsonObject() is false.

Common situations: Pre-serializing documents to strings and then embedding those strings in the array; pipelines that mix scalars and objects; accidental use of JSON arrays of values (e.g. bulk column values) rather than arrays of documents.

Understand the failure class

Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.

Related errors


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