Go Mongodb Error Cannot create field X in element {Y: null}

3 minute read

Today we had a MongoDB 3.6 collection with the following documents:

db.getCollection('person').insertMany([
    {"name": "Odyseas", "surname": "Androutsos", "profilePicture": null},
    {"name": "Theodoros", "surname": "Kolokotronis", "profilePicture": null},
    {"name": "Ioannis", "surname": "Makrygiannis", "profilePicture": null},
    {"name": "Ioannis", "surname": "Kapodistrias", "profilePicture": null},
    {"name": "Emanouil", "surname": "Pappas", "profilePicture": null}
])

and we wanted to update them with Go using mongodb/mongo-go-driver in order to become like this:

[{
    "name": "Ioannis",
    "surname": "Kapodistrias",
    "profilePicture": {
        "image":{
            "iconUrl":null,
            "retrievalStatus": "NOT_FOUND",
            "lastSuccessfulRetrieval": ISODate("2021-07-13T10:00:00.000Z")
        }
    }
},
{
    "name": "Ioannis",
    "surname": "Makrygiannis",
    "profilePicture": {
        "image":{
            "iconUrl":null,
            "retrievalStatus": "NOT_FOUND",
            "lastSuccessfulRetrieval": ISODate("2021-07-13T10:00:00.000Z")
        }
    }
}]

. We were using the following update statement:

db.getCollection('person').update(
    { "name": "Ioannis" },
    {
        "$set": {
            "profilePicture.image.iconUrl": null,
            "profilePicture.image.retrievalStatus": "NOT_FOUND",
            "profilePicture.image.lastSuccessfulRetrieval":   ISODate("2021-07-13T10:00:00.000Z"),
        }
    },
    {multi:true})

however the MongoDB driver was returning this error:

Cannot create field 'image' in element {profilePicture: null}

Initially we thought that something is wrong with the single update() command and we tried in mongo shell the updateMany():

db.getCollection('person').updateMany(
    { "name": "Ioannis" },
    {
        "$set": {
            "profilePicture.image.iconUrl": null,
            "profilePicture.image.retrievalStatus": "NOT_FOUND",
            "profilePicture.image.lastSuccessfulRetrieval":   ISODate("2021-07-13T10:00:00.000Z"),
        }
    })

However it returned a quite similar error:


Failed to execute script.

Error:
WriteError({
	"index" : 0,
	"code" : 28,
	"errmsg" : "Cannot create field 'image' in element {profilePicture: null}",
	"op" : {
		"q" : {
			"surname" : "Manios"
		},
		"u" : {
			"$set" : {
				"profilePicture.image.iconUrl" : null,
				"profilePicture.image.retrievalStatus" : "NOT_FOUND",
				"profilePicture.image.lastSuccessfulRetrieval" : ISODate("2021-07-13T10:00:00Z")
			}
		},
		"multi" : true,
		"upsert" : false
	}
}) :
WriteError({
	"index" : 0,
	"code" : 28,
	"errmsg" : "Cannot create field 'image' in element {profilePicture: null}",
	"op" : {
		"q" : {
			"surname" : "Manios"
		},
		"u" : {
			"$set" : {
				"profilePicture.image.iconUrl" : null,
				"profilePicture.image.retrievalStatus" : "NOT_FOUND",
				"profilePicture.image.lastSuccessfulRetrieval" : ISODate("2021-07-13T10:00:00Z")
			}
		},
		"multi" : true,
		"upsert" : false
	}
})
WriteError@src/mongo/shell/bulk_api.js:458:48
mergeBatchResults@src/mongo/shell/bulk_api.js:855:49
executeBatch@src/mongo/shell/bulk_api.js:919:13
Bulk/this.execute@src/mongo/shell/bulk_api.js:1163:21
DBCollection.prototype.updateMany@src/mongo/shell/crud_api.js:690:17
@(shell):1:1

We searched for the error in the internet but we could not understand where we are wrong:

After some time and numerous attempts, we realised that MongoDB was trying to tell us that it cannot create the subdocument:

"image":{
    "iconUrl":null,
    "retrievalStatus": "NOT_FOUND",
    "lastSuccessfulRetrieval": ISODate("2021-07-13T10:00:00.000Z")
}

inside a field which is alread assigned to null:

"profilePicture": null

So with a small change, the update statement works:

// ------
// BEFORE
// ------
// THIS DOES NOT WORK AND CONFUSES MONGODB. 
db.getCollection('person').update(
    { "name": "Ioannis" },
    {
        "$set": {
            "profilePicture.image.iconUrl": null,
            "profilePicture.image.retrievalStatus": "NOT_FOUND",
            "profilePicture.image.lastSuccessfulRetrieval":   ISODate("2021-07-13T10:00:00.000Z"),
        }
    },
    {multi:true}
)

// ------
// AFTER
// ------
// THIS WORKS
db.getCollection('person').update(
    { "name": "Ioannis" },
    {
        "$set": {
            "profilePicture": {
                "image": {
                    "iconUrl": null,
                    "retrievalStatus": "NOT_FOUND",
                    "lastSuccessfulRetrieval":   ISODate("2021-07-13T10:00:00.000Z"),
                }
            }
        }
    },
    {multi:true}
)

We tested the example in the following versions (running db.version() in Mongo shell):

  1. CosmosDB for MongoDB 3.6.0
  2. MongoDB 3.6.22
  3. MongoDB 4.4.0

and all behave identically.

We hope this helped you and you gain some minutes instead of searching in the web to find a solution! Greetings from our hot Greece with 40 °C!

Comments