Cannot extend Go slice / Can't delete from Go slice

Trying to push or pop an array directly when it’s returned results in the errors

“Cannot extend Go slice” or “Can’t delete from Go slice”.

I’ve narrowed it down to the following steps:

  1. create a new document with an array field
  2. query the document
  3. try to push or pop the array, as in doc.array.push(elem)
  4. observe the error

This was unexpected and extremely difficult to track down – as of when I was looking, there were exactly 16 google results for “Cannot extend Go slice”, none of which were helpful.

My guess is Realm is written in Go and this is a side effect.

Is it possible to get this fixed, or at the very least, provide a more useful error message?

I understand that mongo provides the $push and $pop operators, but for my use case where I’m making many changes to the same document, they are not the best solution.


Workaround:

I created a local function:

// sample use
doc.array = pushtoMongoArray(doc.array, 'new element);

function pushToMongoArray(array, elem) {
    // map the array to itself to force it out of the weird not-an-array object type, then push to it
    (array = array.map(i => i)).push(elem)
    return array;
}

Repro function, pass in different ‘pattern’ ints for executing different code blocks. (start with pattern = 1)

exports = async function (pattern) {

    var collection = context.services.get("mongodb-atlas").db("test").collection("arrayTest");
    var doc = await collection.findOne({})

    console.log('doc', JSON.stringify(doc))
    if (!doc) {
        collection.insertOne({ "array": [] });

        if (pattern === 1) {
            return;
        }
    }

    // FAILS
    if (doc.array && pattern === 2) {
        // fails here
        doc.array.push('simple push');

        // doesn't get far enough to error on "'update' is not a function"
        await collection.update({}, doc);
    }

    // PASSES
    if (doc.array && pattern === 3) {
        doc.array = ['array replace'];
        await collection.updateOne({}, doc);
    }

    // FAILS wih "Cannot delete from Go slice"
    if (doc.array && doc.array.length > 0 && pattern === 4) {
        console.log('try pop element from array')
        doc.array.pop();
        await collection.updateOne({}, doc);
    }
}