Inconsistent Validation Errors When Replacing Plots but Reusing DataSources

When replacing a plot with a variant copy that draws from the same DataSources as the original, a validation error preventing the replacement may inconsistently occur.

See the following minimal example:

from bokeh.layouts import column
from bokeh.models.widgets import Button
from bokeh.models.sources import ColumnDataSource
from bokeh.plotting import figure, curdoc

data1 = {‘x’: list(range(20,3020)), ‘y’: list(range(20,3020))}
data2 = {‘x’: list(range(20,3020)), ‘y’: list(range(50,3050))}
data3 = {‘x’: list(range(20,3020)), ‘y’: list(range(80,3080))}
source1 = ColumnDataSource(data=data1)
source2 = ColumnDataSource(data=data2)
source3 = ColumnDataSource(data=data3)

origplot = figure(plot_height=500, plot_width=600)
for src in [source1, source2, source3]:
origplot.line(‘x’,‘y’,source=src)

but = Button(label=“Change Y-Axis Type”)
col = column(origplot, but)

log = False
def replace_plot():
global log
log = not log

newplot = figure(plot_height=500, plot_width=600)
if log:
    newplot.y_mapper_type = 'log'

for src in [source1, source2, source3]:
    newplot.line('x','y',source=src)
col.children[0] = newplot

but.on_click(replace_plot)
curdoc().add_root(col)

``

Usually, clicking the button will replace the current plot with another showing the same data but with a different y-axis mapping (switching log for linear and vice-versa). Sometimes, however, the replacement fails, with the following error message in the console:

[bokeh] Error handling message: Error: Instance property ‘data_source’ given invalid value: [object Object], [object MessageEvent]

``

As this is fairly unhelpful, I dug down somewhat; the top portion of the stack trace runs as follows:

Prop.validate
exports.Property.Property._init
exports.Property.Property.update
exports.HasProps.HasProps.attach_document
exports.Document.Document._recompute_all_models
exports.Document.Document._invalidate_all_models
exports.LayoutDOMView.LayoutDOMView.build_child_views
triggerEvents

``

The value in question usually looks like

Object { id: “[long-id-string]”, type: “ColumnDataSource” }

``

at time of exception.

This seems to me like a bug; unfortunately its behavior is quite inconsistent - sometimes occurring on the first replacement, sometimes only after many.

The more DataSources or the larger the underlying data, the easier it has been to trip the error.

···

=============================

Additional Notes:

I have occasionally observed a similar error, but on Instance property ‘toolbar’ rather than ‘data_source’.

It appears that the error can be avoided by constructing new DataSources each time (rather than maintaining the old ones), e.g.

def replace_plot():

for data in [data1, data2, data3]:
src = ColumnDataSource(data=data)
newplot.line(‘x’,‘y’,source=src)

``

Behavior was observed on Chrome 56.0 and Firefox 47.0, the Bokeh app being run with bokeh serve (Bokeh 0.12.4 / Python 3.5.2).