Callback Gotchas

There are some aspects of how Dash works that can be counter-intuitive. This
can be especially true of how the callback system works. This section
outlines some common Dash gotchas that you might encounter as you start
building out more complex Dash apps. If you have read through the rest of
the Dash Tutorial and are encountering unexpected behaviour, this is a
good section to read through. If you still have residual questions, the
Dash Community forums is a great place
to ask them.

Callbacks require their Inputs, States, and Output to be present in the layout

By default, Dash applies validation to your callbacks, which performs checks
such as validating the types of callback arguments and checking to see
whether the specified Input and Output components actually have the
specified properties. For full validation, all components within your
callback must exist in the layout when your app starts, and you
will see an error if they do not.

However, in the case of more complex Dash apps that involve dynamic
modification of the layout (such as multi-page apps), not every component
appearing in your callbacks will be included in the initial layout. You can
remove this restriction by disabling callback validation like this:

app.config.suppress_callback_exceptions = True

Callbacks require all Inputs and States to be rendered on the page

If you have disabled callback validation in order to support dynamic
layouts, then you won’t be automatically alerted to the situation where a
component within a callback is not found within a layout. In this situation,
where a component registered with a callback is missing from the layout, the
callback will fail to fire. 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.

A component/property pair can only be the Output of one callback

For a given component/property pair (eg 'my-graph', 'figure'), it can
only be registered as the Output of one callback. If you want to associate
two logically separate sets of Inputs with the one output
component/property pair, you’ll have to bundle them up into a larger
callback and detect which of the relevant Inputs triggered the callback
inside the function. For html.Button elements, detecting which one
triggered the callback can be done using the n_clicks_timestamp
property. For an example of this, see the question in the FAQ, How do I
determine which Input has changed?

All callbacks must be defined before the server starts

All your callbacks must be defined before your Dash app’s server starts
running, which is to say, before you call app.run_server(debug=True). This means
that while you can assemble changed layout fragments dynamically during the
handling of a callback, you can’t define dynamic callbacks in response to
user input during the handling of a callback. If you have a dynamic
interface, where a callback changes the layout to include a different set of
input controls, then you must have already defined the callbacks required to
service these new controls in advance.

For example, a common scenario is a Dropdown component that updates the
current layout to replace a dashboard with another logically distinct
dashboard that has a different set of controls (the number and type of which
might which might depend on other user input) and different logic for
generating the underlying data. A sensible organisation would be for each of
these dashboards to have separate callbacks. In this scenario, each of these
callbacks much then be defined before the app starts running.

Generally speaking, if a feature of your Dash app is that the number of
Inputs or States is determined by a user’s input, then you must
pre-define up front every permutation of callback that a user can
potentially trigger. For an example of how this can be done programmatically
using the callback decorator, see this Dash Community forum

All Dash Core Components in a layout should be registered with a callback.

Note: This section is present for legacy purposes. Prior to v0.40.0, setProps was only defined if the component was connected to a
callback. This required complex state management within the component like this.
Now, setProps is always defined which should simplify your component’s state
management. Learn more in this community forum topic.

If a Dash Core Component is present in the layout but not registered with a
callback (either as an Input, State, or Output) then any changes to its
value by the user will be reset to the original value when any callback
updates the page.

This is a known issue and you can track its status in this GitHub

Callback Definitions Don’t Need To Be In Lists

As of Dash 1.15.0, Input, Output, and State in callback definitions don’t need to be in lists. You still need to provide Output items first, then Input items, then State, and the list form is still supported. In particular, if you want to return a single output item wrapped in a length-1 list, you should still wrap the Output in a list. This can be useful for procedurally-generated callbacks.