Black Lives Matter. Please consider donating to Black Girls Code today.

Getting "Error loading dependencies" error when having an undeclared dcc.Input component

This is the dummy example I was trying to run.

If dcc.Input (commented below) is not present this will not load even though this “gotcha” (Callbacks require their Inputs , States , and Output to be present in the layout) implies that it should work?

any ideas what might be going on?

import dash_core_components as dcc
import dash_html_components as html                                             
from dash.dependencies import Input, Output, State                              
                                                                              
                                                                              
app = dash.Dash(__name__)                                                       
app.css.append_css({                                                            
    'external_url': ('https://stackpath.bootstrapcdn.com/'                      
                     'bootstrap/4.1.1/css/bootstrap.min.css')                   
    })                                                                          
                                                                              
                                                                              
app.layout = html.Div([                                                         
    html.Div(id='output'),                                                      
    html.Button(id='button', children='click'),                                 
    html.Br(),                                                                  
    # dcc.Input(id='my-input', value='hello'),                                  
])                                                                              
                                                                              
                                                                              
app.config.suppress_callback_exceptions = True                                  
                                                                              
                                                                              
@app.callback(                                                                  
    Output('output', 'children'),                                               
    [                                                                           
        Input('button', 'n_clicks'),                                            
        Input('my-input', 'value')                                              
    ]                                                                           
)                                                                               
def update1(*args):                                                             
    print('Out')                                                                
    print(args)                                                                 
    print('Out - END')                                                          
    return 'ok'                                                                 
                                                                              
                                                                              
if __name__ == '__main__':                                                      
    app.run_server(debug=True, port=8888)

From what I understand, the “gotcha” you’re referencing is actually talking about a different issue.

I’m working on a multi-page app and I have many dynamic elements in each page. As a consequence, I have many callbacks referencing items that don’t “initially” exist on the page. That’s why I use “app.config.suppress_callback_exceptions = True”. It allows me to avoid the error message “Hey, you have callbacks with unknown Output/Input/State, get out!”

Your problem is different.
You have a callback that has an INPUT that exists in the initial layout. So what happens? It triggers at launch.
But wait, there’s another INPUT but it doesn’t exists. So Dash is like “can’t make this work, I’m missing one argument”

What I’m trying to emphasize here is the difference between:

  • Dash checks that all the elements for all your callbacks are available on the dash layout (which is the “gotcha” part)
  • When a callback is FIRED, all of his elements must be on the layout

At least that’s how I understand it, and that would explain your situation

in my example the page won’t even load. The expected behaviour was that the page would load, ie I’d have a visible button and then clicking it would do nothing because the dcc.Input component is commented out. Do you disagree?

I’d say that’s normal

Your page won’t load because when loading the layout, he tries to trigger your callback but some of its INPUT are not on the page, so it can’t execute the callback, which creates an error.

We’re talking about two types of error:

  • Error when at least ONE of any of your callbacks’s output/input/state are not in the original layout
  • Error when at least ONE of your callback output/input/state are not in the current layout when the callback is fired

The issue I think you have is: your callback fires but one of his inputs does not exist.
What the “gotcha” guide says is different. It explains that you might get an error if you have elements in callbacks that are not in the original layout (but they must exist when the callback is fired/triggered/called)

thank you for clarifying I think I’m confused about what needs to be in the original layout vs in the layout at any point.

Also, I’m confused about the following. If you have callbacks associated with parts of the layout that are not currently then I’d expect the layout to properly load but the callback to simply not fire rather than return an error as per this gotcha:

For example, if you define a callback with only a subset of the specified Inputs present in the current page layout, the callback will simply not fire at all.

I’m not at home so I can’t test it out, but in my personal project I don’t have any scenario where only part of my inputs are available.

What I BELIEVE to be your current issue is:

  • Run Dash server
  • Dash checks ALL the callbacks for element that would be missing in the initial layout (that’s the gotcha guide part)
  • Dash tries to render the initial layout
  • Dash sees you have a callback that takes X as input… and X is on the page
  • Dash triggers the callback, but is missing the 2nd argument of the function (2nd input)
  • Dash is upset. Y U DO DIS TO ME?

I might be wrong, maybe someone else will have a different explanation. But that’s how I understand it. And in the app I’m working on, I make sure all my output/input/state are on the page WHEN the callback is fired

I’m not sure I follow, the second example here doesn’t have all layout items initially set up and it will fire all callbacks when initialised right?

Callbacks are fired when one of the INPUT changes. However, rendering/creating an INPUT counts as changing it. So basically, a callback fires:

  • When one of the Input is created
  • When one of the Input is changed

When you have a multi-page app, your app will have a initial layout (app.layout) with at least 2 elements:

  • dcc.Location (that’s your URL)
  • html.Div that’s gonna be your output

Now you create a callback that takes dcc.Location as Input and your Div as Output. The role of this callback is to return the “layout for the called URL”. So it’s something like:

if url == '/': # Homepage
   return home.layout
elif url == 'test': # Specific page
   return test.layout
...

(I use a dict of URLs to make it simpler)

So here’s what happens when you launch the app:

  • Dash launches the app
  • Dash checks if all your callbacks’ elements are on the page (no, they are not because you have like 20 different pages on your website so obviously all the elements are not right here on a single page. That’s why you need app.config.suppress_callback_exceptions = True)
  • Dash tries to render your page:
    • Dash calls the initial app.layout
    • Dash renders the dcc.Location element… and it fires the associated callback
    • The callback gets the URL and call your other layout (and its callbacks)
    • Our url is ‘/’ so it calls the home layout (For the sake of argument, lets say our home doesn’t have callback)
    • Dash renders the elements from your imported layout in the Div Content (all will again fire callbacks if some of its elements are associated with some)
2 Likes