Bug: Periodic error in StaticGeometryPerMaterialBatch.update

1. A concise explanation of the problem you're experiencing.

Periodically my Cesium instance will crash with the following exception:
TypeError: Cannot read property 'update' of undefined
    at StaticGeometryPerMaterialBatch.update (https://***/CesiumUnminified/Cesium.js:127895:33)

In StaticGeometryPerMaterialBatch.prototype.update it appears that an array length is determined early, but then code is executed that may destroy elements of the array. That initial length is then used on a subsequent call, ostensibly trying to use indexes of elements that no longer exists.

Skipping any undefined items seems to keep the instance going, but this is so deep in Cesium logic that I have no idea of the implications of doing that.

4. The Cesium version you're using, your operating system and browser.

Cesium 1.36, Chrome 60.0.3112.101, Windows 7 Pro

Hi Dave,

Are you running your code on Sandcastle when this happens? Or when you are developing locally?

Thanks,

Gabby

Locally with a fairly complex implementation, so difficult to reproduce in a simple example since I’m not sure what’s triggering it.

Hmm, I’m not really sure what’s going on here, could you narrow it down to what’s happening when you get the error? If we figure out generally what’s causing the error I can open an issue in GitHub if it ends up being a bug. Could you take a stab at making a Sandcastle example?

Well, the direct bug itself is easy enough to see:

StaticGeometryPerMaterialBatch.prototype.update = function(time) {
    var i;
    var items = this._items;
    var length = items.length;                           **<= #1 initial length recorded**
    for (i = length - 1; i >= 0; i--) {
        var item = items[i];
        if (item.invalidated) {
            items.splice(i, 1);                          **<= #2 actual length may changes**
            var updaters = item.updaters.values;
            var updatersLength = updaters.length;                   
            for (var h = 0; h < updatersLength; h++) {
                this.add(time, updaters[h]);
            }
            item.destroy();
        }
    }
    var isUpdated = true;
    for (i = 0; i < length; i++) {                       **<= #3 initial length still assumed**
        isUpdated = items[i].update(time) && isUpdated;  **<= #4 potential error**
    }                
    return isUpdated;
}; 

The length variable either needs to be reset after the first for-loop, or the existence of items[i] needs to be verified within the bottom for-loop before .update(time) is called.

I’m not entirely sure what “invalidated” means on an item but it’s being triggered, on some items, when I change an entity’s color via entity.polyline.material.color = new Cesium.Color(1,1,1,0.2);

Thanks fro the snippet, Dave!

This was previously reported and we have an issue open for this here: https://github.com/AnalyticalGraphicsInc/cesium/issues/5379

Thanks,

Gabby

Hi David,

This issue has been fixed and will be available in the 1.43 release on March 1st. Let me know if you are still experiencing problems!

Thanks,

Hannah