AttributeError: 'NoneType' object has no attribute 'document'

Debugging some code, I have noticed this bokeh server bug. If the function returning the view depends on a parameter p and if a callback ,with some long computation which update the parameter p, is called several times rapidly. The first callback will return his result but the others will raise a bokeh server error AttributeError: ‘NoneType’ object has no attribute ‘document’

the error log :

bokeh.server.protocol_handler - ERROR - error handling message
 message: Message 'PATCH-DOC' content: {'events': [{'kind': 'MessageSent', 'msg_type': 'bokeh_event', 'msg_data': {'event_name': 'tap', 'event_values': {'sx': 127, 'sy': 55, 'x': 0.35585585585585583, 'y': 0.8813765182186235}}}], 'references': []} 
 error: AttributeError("'NoneType' object has no attribute 'document'")
Traceback (most recent call last):
  File "C:\Users\sciarra2\miniconda37\envs\datascience\lib\site-packages\bokeh\server\protocol_handler.py", line 90, in handle
    work = await handler(message, connection)
  File "C:\Users\sciarra2\miniconda37\envs\datascience\lib\site-packages\bokeh\server\session.py", line 67, in _needs_document_lock_wrapper
    result = func(self, *args, **kwargs)
  File "C:\Users\sciarra2\miniconda37\envs\datascience\lib\site-packages\bokeh\server\session.py", line 261, in _handle_patch
    message.apply_to_document(self.document, self)
  File "C:\Users\sciarra2\miniconda37\envs\datascience\lib\site-packages\bokeh\protocol\messages\patch_doc.py", line 100, in apply_to_document
    doc._with_self_as_curdoc(lambda: doc.apply_json_patch(self.content, setter))
  File "C:\Users\sciarra2\miniconda37\envs\datascience\lib\site-packages\bokeh\document\document.py", line 1150, in _with_self_as_curdoc
    return f()
  File "C:\Users\sciarra2\miniconda37\envs\datascience\lib\site-packages\bokeh\protocol\messages\patch_doc.py", line 100, in <lambda>
    doc._with_self_as_curdoc(lambda: doc.apply_json_patch(self.content, setter))
  File "C:\Users\sciarra2\miniconda37\envs\datascience\lib\site-packages\bokeh\document\document.py", line 398, in apply_json_patch
    self._trigger_on_message(event_json["msg_type"], event_json["msg_data"])
  File "C:\Users\sciarra2\miniconda37\envs\datascience\lib\site-packages\bokeh\document\document.py", line 687, in _trigger_on_message
    cb(msg_data)
  File "C:\Users\sciarra2\miniconda37\envs\datascience\lib\site-packages\bokeh\document\document.py", line 354, in apply_json_event
    model._trigger_event(event)
  File "C:\Users\sciarra2\miniconda37\envs\datascience\lib\site-packages\bokeh\util\callback_manager.py", line 87, in _trigger_event
    invoke()
  File "C:\Users\sciarra2\miniconda37\envs\datascience\lib\site-packages\bokeh\util\callback_manager.py", line 74, in invoke
    callback(event)
  File "C:\Users\sciarra2\miniconda37\envs\datascience\lib\site-packages\holoviews\plotting\bokeh\callbacks.py", line 404, in on_event
    if not self._active and self.plot.document:
AttributeError: 'NoneType' object has no attribute 'document' 

Here is a toy example :

import numpy as np
import param
import panel as pn
from holoviews import streams
import holoviews as hv


class App_debug(param.Parameterized):
    counter=param.Integer(0)
    
    def __init__(self,**params):
        super().__init__(**params)
        self.plot=hv.Curve([[0,0],[1,1]])
        rangex=streams.Tap(source=self.plot)
        rangex.add_subscriber(self.recup_range)
    
    
    def recup_range(self,x,y):
            self.counter+=1
            display(self.counter)
            display(np.mean(np.fft.fft2(np.random.rand(11000,11000))))

    
    def view(self):
        return self.plot

viewer=App_debug()

pn.Row(viewer.view).show()

By doing a triple clic (not double) on the plot, the tap stream will run 2 callbacks, the first one will work but not the other.

AttributeError means that there was an Error that had to do with an Attribute request. In general, when you write x.y, y is the purported attribute of x. NoneType means that instead of an instance of whatever Class or Object you think you’re working with, you’ve actually got None. That usually means that an assignment or function call up failed or returned an unexpected result.

mylist = mylist.sort()

The sort() method of a list sorts the list in-place, that is, mylist is modified. But the actual return value of the method is None and not the list sorted. So you’ve just assigned None to mylist. If you next try to do, say, mylist.append(1) Python will give you this error.