Panel tabs error on closing tab

Hello,

My environment: Python 3.7.10, panel==0.10.3, holoviews==1.14.0, bokeh==2.2.3, tornado==6.1

I’m having the following problem. I want to use tabs to show plots on user’s demand. That’s why I have a button that adds a new tab with a plot. I also need my tabs to be closable, because the user will likely see the plots in one tab, then go to another tab, then look at a plot and generate a new tab, and repeat those steps, potentially many times.

Here is an example code:

import panel as pn
import holoviews as hv
import numpy as np

def make_img():
    ls = np.linspace(0, 10, 200)
    xx, yy = np.meshgrid(ls, ls)
    bounds=(-1,-1,1,1)   # Coordinate system: (left, bottom, right, top)
    return hv.Image(np.sin(xx)*np.cos(yy), bounds=bounds)

tabs = pn.Tabs(make_img(), closable=True, dynamic=True)

button = pn.widgets.Button(name="Add tab")
button.on_click(lambda e: tabs.append(make_img()))

pn.Row(tabs, button).servable()

and the workflow:

The problem is that sometimes (not every tab closing leads to error), an error appear when I close a tab. In particular to reproduce it:

  1. Click button to add a new tab.
  2. Close that tab without opening it.
    Now you should see an error message in console, and also app stops reacting to button clicks. The error message:
2021-04-13 11:26:55,136 Exception in callback functools.partial(<bound method IOLoop._discard_future_result of <tornado.platform.asyncio.AsyncIOMainLoop object at 0x7fe614810e50>>, <Task finished coro=<_needs_document_lock.<locals>._needs_document_lock_wrapper() done, defined at /home/rafal/venvs/my-env/lib/python3.7/site-packages/bokeh/server/session.py:51> exception=TypeError("unhashable type: 'list'")>)
Traceback (most recent call last):
  File "/home/rafal/venvs/my-env/lib/python3.7/site-packages/tornado/ioloop.py", line 741, in _run_callback
    ret = callback()
  File "/home/rafal/venvs/my-env/lib/python3.7/site-packages/tornado/ioloop.py", line 765, in _discard_future_result
    future.result()
  File "/home/rafal/venvs/my-env/lib/python3.7/site-packages/bokeh/server/session.py", line 71, in _needs_document_lock_wrapper
    result = await result
  File "/home/rafal/venvs/my-env/lib/python3.7/site-packages/tornado/gen.py", line 216, in wrapper
    result = ctx_run(func, *args, **kwargs)
  File "/home/rafal/venvs/my-env/lib/python3.7/site-packages/panel/reactive.py", line 194, in _change_coroutine
    self._change_event(doc)
  File "/home/rafal/venvs/my-env/lib/python3.7/site-packages/panel/reactive.py", line 204, in _change_event
    self._process_events(events)
  File "/home/rafal/venvs/my-env/lib/python3.7/site-packages/panel/reactive.py", line 187, in _process_events
    self.param.set_param(**self._process_property_change(events))
  File "/home/rafal/venvs/my-env/lib/python3.7/site-packages/param/parameterized.py", line 1472, in set_param
    self_._batch_call_watchers()
  File "/home/rafal/venvs/my-env/lib/python3.7/site-packages/param/parameterized.py", line 1611, in _batch_call_watchers
    self_._execute_watcher(watcher, events)
  File "/home/rafal/venvs/my-env/lib/python3.7/site-packages/param/parameterized.py", line 1573, in _execute_watcher
    watcher.fn(*args, **kwargs)
  File "/home/rafal/venvs/my-env/lib/python3.7/site-packages/panel/reactive.py", line 175, in _param_change
    self._update_model(events, msg, root, model, doc, comm)
  File "/home/rafal/venvs/my-env/lib/python3.7/site-packages/panel/layout/tabs.py", line 120, in _update_model
    super(Tabs, self)._update_model(events, msg, root, model, doc, comm)
  File "/home/rafal/venvs/my-env/lib/python3.7/site-packages/panel/layout/base.py", line 69, in _update_model
    state._views[ref][0]._preprocess(root)
  File "/home/rafal/venvs/my-env/lib/python3.7/site-packages/panel/viewable.py", line 417, in _preprocess
    hook(self, root)
  File "/home/rafal/venvs/my-env/lib/python3.7/site-packages/panel/pane/holoviews.py", line 614, in link_axes
    range_map[fig.x_range.tags[0]].append((fig, p, fig.xaxis[0], fig.x_range))
TypeError: unhashable type: 'list'

What can I do to avoid this problem?

Thanks!

As a workaround, I used Tabs(closable=False) and just added a button that a user can click to close the tab.