Skip to content

Cyclical callback results in "Error loading dependencies" message, no error message in console. #228

Closed

Description

@ThomasProctor

If a callback has the same output and input, the "Error loading dependencies" message is shown in the browser, but no error is raised in the console.

Here is a MWE, a div that just counts the number of times the callback has occurred:

import re
from time import sleep

import dash
import dash_html_components as html


app = dash.Dash()
app.layout = html.Div("Callback run 0 times", id='counter-div')


@app.callback(dash.dependencies.Output(component_id='counter-div',
                                       component_property='children'),
              [dash.dependencies.Input(component_id='counter-div',
                                       component_property='children')])
def increment_counter(counter_message):
    regex = re.compile("Callback run (\d+) times")
    result = regex.search(counter_message)
    current_count = int(result.group(1))
    new_count = current_count + 1
    sleep(1)
    return "Callback run {:d} times".format(new_count)


if __name__ == "__main__":
    app.run_server(debug=True, port=65002)

I produced this on Python 3.4.3, both in Firefox and Chromium, with this environment:

certifi==2018.1.18
chardet==3.0.4
click==6.7
dash==0.21.0
dash-core-components==0.21.0
dash-html-components==0.9.0
dash-renderer==0.11.3
decorator==4.2.1
Flask==0.12.2
Flask-Compress==1.4.0
idna==2.6
ipython-genutils==0.2.0
itsdangerous==0.24
Jinja2==2.10
jsonschema==2.6.0
jupyter-core==4.4.0
MarkupSafe==1.0
nbformat==4.4.0
plotly==2.5.0
pytz==2018.3
requests==2.18.4
six==1.11.0
traitlets==4.3.2
urllib3==1.22
Werkzeug==0.14.1

The same issue arises if a network of callbacks is cyclical, eg a callback with element A as an input that outputs to element B, which is the input to a callback that outputs to element A.

Allowing cyclical callbacks would be nice, but there should at least be an error raised indicating the problem. I also can't find anything in the documentation indicating that cyclical callbacks are not possible, but I might not be searching for the right terms.

#125 Seems to have become a catchall for every instance of the "Error loading dependencies" message, regardless of the underlying cause. I thought it would be better to create a separate issue, as I'm fairly certain what the cause is.

Activity

  1. antisrdy commented on Apr 5, 2018

    @antisrdy

    Same error here. Got the "Error loading dependencies" message triggered by a trivial cycle (element A <-> element B). @ThomasProctor, have you eventually come with a workaround?

  2. ThomasProctor commented on Apr 26, 2018

    @ThomasProctor
    Author

    @antisrdy I think the workaround is: you're just not supposed to do this.

    The bug, as I see it, is that it doesn't tell you what you're doing wrong.

  3. antisrdy commented on Apr 26, 2018

    @antisrdy

    @ThomasProctor This workaround looks pretty accurate ;) And this is eventually what I did.

    I agree on the fact that cyclical callbacks would deserve a proper error message.

    Even better, they could be taken care of. Unfortunately, I'm personally not skilled enough in web development to do so. The only thing I was able to manage is solving my cyclical issue in React: https://codesandbox.io/s/5yl0y9pww4. But no more :/

  4. zouhairm commented on Aug 31, 2018

    @zouhairm

    I actually found myself in a situation where I'd like to use cyclical callbacks, but with the cycle being broken by raising a "PreventUpdate()" after some condition is met. Is there a way to disable the cycle checking short of editing bundle.js ?

  5. nicolaskruchten commented on Nov 19, 2018

    @nicolaskruchten
    Contributor

    There really should be something in the Python console telling you about the cycle, not just in the JS console.

  6. vtslab commented on Apr 25, 2019

    @vtslab

    I published a workaround at:

    http://yaaics.blogspot.com/2019/03/circular-references-in-plotlydash.html

    As stated in the blog, allowing intended circular references that can be broken with raise PreventUpdate is still the prefered final solution.

  7. alexcjohnson commented on May 22, 2019

    @alexcjohnson
    Collaborator

    This particular cycle we now do catch on the Python side, with dash.exceptions.SameInputOutputException

    However, a nontrivial cycle is still a problem that gives the dreaded "Error loading dependencies" with no indication anywhere what caused it. Here's a simple example, that works fine if you comment out either one of the callbacks but fails with both active:

    import dash
    import dash_html_components as html
    from dash.dependencies import Input, Output
    
    app = dash.Dash()
    app.layout = html.Div([html.Div('a', id='a'), html.Div('b', id='b')])
    
    @app.callback(Output('a', 'children'), [Input('b', 'children')])
    def a(b):
        return b
    
    @app.callback(Output('b', 'children'), [Input('a', 'children')])
    def b(a):
        return (a or '') + 'A'
    
    if __name__ == "__main__":
        app.run_server(debug=True)

    We need to have the devtools capture and display these errors. I don't see us catching cyclic callbacks on the Python side - even if it worked for the static case it can't work for dynamically-generated callbacks where the back-end doesn't know the whole layout. So the front end will need to have this check, therefore it's redundant to include it in the back end even if in certain cases that would improve the dev experience.

    Separately, I'm transferring the issue of allowing cycles and trusting the dev to break them appropriately here from the dash-renderer repo, in prep for merging the two repos -> #730. This issue is just about reporting it when an error is the desired outcome.

  8. gvwilson commented on Jun 3, 2024

    @gvwilson
    Contributor

    @alexcjohnson may I close this one?

  9. alexcjohnson commented on Jun 3, 2024

    @alexcjohnson
    Collaborator

    @gvwilson might be worth testing the example I gave to see what the current behavior is, but given that there have been no comments for 5 years I bet it’s resolved

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions