Using a simple, vanilla insert like the below, the driver reports:
An EndArray value cannot be written to the root level of a BSON document
Simple reproduction scenario:
final MongoClient mongoClient = MongoClients.create( MongoClientSettings.builder() .applyConnectionString(new ConnectionString("mongodb://localhost:27017")) .uuidRepresentation(UuidRepresentation.STANDARD) .build() ); mongoClient.getDatabase("unittest") .getCollection("listError") .insertOne( new Document() .append("_id", new org.bson.types.ObjectId()) .append( "items", Collections.singletonList( new Document() .append("_id", new org.bson.types.ObjectId()) ) ) );
The stack trace is:
org.bson.BsonInvalidOperationException: An EndArray value cannot be written to the root level of a BSON document. at org.bson.AbstractBsonWriter.throwInvalidState(AbstractBsonWriter.java:740) at org.bson.AbstractBsonWriter.checkPreconditions(AbstractBsonWriter.java:701) at org.bson.AbstractBsonWriter.writeEndArray(AbstractBsonWriter.java:341) at com.mongodb.internal.connection.BsonWriterDecorator.writeEndArray(BsonWriterDecorator.java:68) at com.mongodb.internal.connection.LevelCountingBsonWriter.writeEndArray(LevelCountingBsonWriter.java:66) at com.mongodb.internal.connection.IdHoldingBsonWriter.writeEndArray(IdHoldingBsonWriter.java:133) at org.bson.codecs.DocumentCodec.writeIterable(DocumentCodec.java:222) at org.bson.codecs.DocumentCodec.writeValue(DocumentCodec.java:193) at org.bson.codecs.DocumentCodec.writeMap(DocumentCodec.java:212) at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:154) at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:45) at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:63) at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:29) at com.mongodb.internal.connection.SplittablePayload$WriteRequestEncoder.encode(SplittablePayload.java:200) at com.mongodb.internal.connection.SplittablePayload$WriteRequestEncoder.encode(SplittablePayload.java:187) at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:63) at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:29) at com.mongodb.internal.connection.BsonWriterHelper.writeDocument(BsonWriterHelper.java:77) at com.mongodb.internal.connection.BsonWriterHelper.writePayload(BsonWriterHelper.java:59) at com.mongodb.internal.connection.CommandMessage.encodeMessageBodyWithMetadata(CommandMessage.java:145) at com.mongodb.internal.connection.RequestMessage.encode(RequestMessage.java:138) at com.mongodb.internal.connection.CommandMessage.encode(CommandMessage.java:59) at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:247) at com.mongodb.internal.connection.UsageTrackingInternalConnection.sendAndReceive(UsageTrackingInternalConnection.java:99) at com.mongodb.internal.connection.DefaultConnectionPool$PooledConnection.sendAndReceive(DefaultConnectionPool.java:500) at com.mongodb.internal.connection.CommandProtocolImpl.execute(CommandProtocolImpl.java:71) at com.mongodb.internal.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:224) at com.mongodb.internal.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:202) at com.mongodb.internal.connection.DefaultServerConnection.command(DefaultServerConnection.java:118) at com.mongodb.internal.operation.MixedBulkWriteOperation.executeCommand(MixedBulkWriteOperation.java:419) at com.mongodb.internal.operation.MixedBulkWriteOperation.executeBulkWriteBatch(MixedBulkWriteOperation.java:245) at com.mongodb.internal.operation.MixedBulkWriteOperation.access$700(MixedBulkWriteOperation.java:71) at com.mongodb.internal.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:189) at com.mongodb.internal.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:180) at com.mongodb.internal.operation.OperationHelper.withReleasableConnection(OperationHelper.java:500) at com.mongodb.internal.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:180) at com.mongodb.internal.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:71) at com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.execute(MongoClientDelegate.java:207) at com.mongodb.client.internal.MongoCollectionImpl.executeSingleWriteRequest(MongoCollectionImpl.java:1008) at com.mongodb.client.internal.MongoCollectionImpl.executeInsertOne(MongoCollectionImpl.java:469) at com.mongodb.client.internal.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:452) at com.mongodb.client.internal.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:446)
It appears to be because IdHoldingBsonWriter, when it writes its internal EndArray token, finds the wrong state:
@Override public void writeEndArray() { super.writeEndArray(); if (isWritingId()) { getIdBsonWriter().writeEndArray(); if (getIdBsonWriter().getCurrentLevel() == 0) { getIdBsonWriter().writeEndDocument(); id = new RawBsonDocument(getBytes()).get(ID_FIELD_NAME); } } }