Learn how to use Dash Bio for next-gen sequencing & quality control. 🧬Register for the Oct 27 webinar.

[SOLVED] Dash 2.0 switching @app.callback->@app.long_callback causes "A nonexistent object was used in an Input" error

EDIT: I looks like this is a known limitation. Scroll to bottom of post for details.

XPosted from the GitHub issue I created, wasn’t sure best place to raise issue. Hope that is okay.

Describe your context

dash                              2.0.0rc2
dash-auth                         1.3.2
dash-bootstrap-components         0.11.1
dash-core-components              2.0.0rc1
dash-cytoscape                    0.2.0
dash-html-components              2.0.0rc1
dash-renderer                     1.4.0
dash-table                        5.0.0rc1

OS: Windows 10

Describe the bug

A nonexistent object was used in an Input of a Dash callback. The id of this object is generate-video and the property is n_clicks. The string ids in the current layout are: [url, page-content, _long_callback_interval_1, _long_callback_store_1]

Expected behavior

Expect it to run the @app.long_callback decorated function. It does this fine when the code is @app.callback(

Screenshots

Using multi page app structure.

index.py was updated to have:

from dash import dcc, html, Input, Output, State
import dash_auth

from app import app, server

app.py was updated to have:

from dash import Dash

# Diskcache for long callbacks
from dash.long_callback import DiskcacheLongCallbackManager
import diskcache
cache = diskcache.Cache("./cache")
long_callback_manager = DiskcacheLongCallbackManager(cache)

# MORE CODE HERE
app = Dash(__name__, 
           external_stylesheets=[dbc.themes.COSMO], 
           long_callback_manager=long_callback_manager)
server = app.server
conn = connect()  # this is a universal connection that will be used throughout the app
thread1 = threading.Thread(target=check_connection)  # create thread
thread1.start()  # start threaded process
app.config['suppress_callback_exceptions'] = True

video.py contains a callback that worked prior to changing to long_callback

#Imports
import dash_bootstrap_components as dbc
from dash import dcc, html, Input, Output, State, MATCH, ALL
from app import app, conn

####In the function  that returns the layout components####
            dbc.Row(
                dbc.Col(
                    [
                        dbc.Button("Generate Thumbnail and Video", color="success", id="generate-video", size="mr-1"),
                        html.Div(id="thumbnail-image"),
                        html.Div(id="video-generation-state"),
                    ]
                )
            )

####OUTSIDE THAT FUNCTION BELOW####
@app.long_callback(
    Output('thumbnail-image', 'children'),
    [Input('generate-video', 'n_clicks')],
    [State('first-name-output', 'value'),
     State('last-name-output', 'value'),
     ],
    # manager=long_callback_manager,
    # running=[
    #     (Output("video-generation-state", "children"), [""], ["Video generation is running..."]),
    # ],
)
def generate_video(n_clicks, first_name, last_name):
    """
    Docstring here
    """
    if n_clicks:
        # Make a function to wrap text
        time.sleep(90)
        data = [some b64 data]
        return html.Img(className="image",
                        src=f"data:image/png;base64,{data}",
                        style={'height': '50%', 'width': '50%'})
    else:
        return ""

EDIT:

It looks like I may be running into a known limitation.
From the long_callback docs:

If the Input/State/Output dependencies do not exist when the app starts (if they reference components that are generated by another callback), suppress_callback_exceptions=True does not prevent Dash from raising callback validation errors. We recommend the following approach:

  1. The app must provide a validation_layout that contains all of the components referenced by callbacks in the app.
  2. The prevent_initial_call argument to app.long_callback must be set to True.

I am attempting to workaround with

@app.long_callback(
    Output('thumbnail-image', 'children'),
    [Input('generate-video', 'n_clicks')],
    [State('first-name-output', 'value'),],
    prevent_initial_call=True
)

in my video.py file and the below in app.py

app = Dash(__name__,
           external_stylesheets=[dbc.themes.COSMO],
           long_callback_manager=long_callback_manager,
           suppress_callback_exceptions=True)

# Move to app as arg:
# app.config['suppress_callback_exceptions'] = True

This stops me from getting the error, I’ll continue testing to see if it is working.

1 Like