You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Is your feature request related to a problem? Please describe.
In trying to make my applications as modular as possible, I tend to use pattern-matching callbacks just about everywhere. There are many instances, however, where I need to be able to detect which component was triggered (via MATCH) and update a universal component.
Describe the solution you'd like
I would love for the restriction on the MATCH wildcard that requires the same number of MATCH values in the Input ID's and Output ID's to be lifted, allowing for more wildcards in the input than the output. It's my understanding that today's release of allow_duplicate in Dash's Output component should open the door to adding in the aforementioned solution.
Describe alternatives you've considered
The current solution for this use case is to use the ALL wildcard along with the callback context to filter down to the content that I'm ultimately interested in, but that solution does not scale especially well as it requires a lot of information to pass through the network, slowing things down.
Reacted by Ole Jørgen Brønner, Tim Child, pitris90, Alvaro de Miguel, Yuyang Zhang, Thomas Le Meur, Jan, Sean McCarthy, Brady Walters, eltrujo and 4 more
Reacted by Wilfredo Machado, pitris90, Alvaro de Miguel, Sean McCarthy and yblainm
@T4rk1n I think "any MATCH present in the inputs must be present in all the outputs too" is another flavor of the restriction "every output can be connected to only one callback" - it's just that these duplicates come from the same function. So in the same way as we do for multiple callback functions we should be able to relax that restriction when the output that's missing a MATCH specifies allow_duplicate. Seem reasonable?
To make this concrete, I guess we're talking about callbacks that would look like:
@callback(Output("out", "children"),Input({"id": MATCH}, "n_clicks"),State({"id": MATCH}, "id"),prevent_initial_call=True)defcb(_, _id):
returnf"you clicked the button with id {_id['id']}"
Reacted by Milind Sundaram, Lukasz Bandzarewicz, WheatMa, Alvaro de Miguel, Sean McCarthy and Jiahao Hong
I think the validation should be lifted entirely for Output, it makes MATCH awkward to use and I remember removing the validation without any breakage.
It would have exactly the same kind of breakage scenarios as other duplicate outputs, an ambiguity when two callbacks result from the same stimulus. Which is why I think allowing it the same way (with allow_duplicate) makes most sense.
I would also like this restriction to be lifted. I'm trying out a convention where callbacks which modify database state triggers a re-render using a "trigger" output. This does not work with this restriction in place.
For searchability - this is the error message:
`Input` / `State` wildcards not in `Output`s
or
Output X
does not have MATCH wildcards on the same keys as
Output Y
MATCH wildcards must be on the same keys for all Outputs. ALL wildcards need not match, only MATCH
Someone else mentioned that they would like to do partial update based on a MATCH callback. On the surface this also sounds like a reasonable use-case (with the disclaimer that I haven't used partial update enough to really know it makes sense).
EDIT: Thinking a bit further - any scenerio where doing something to a component[1] should trigger a not-local-to-that-component update become cumbersome to implement. Only workaround (other than the one mentioned by OP) I can see is to add dummy outputs per component and route these to the callback implementing the global update.
I would appreciate this restriction lifted too, as it would simplify my callbacks. I was so surprised it doesnt work when I tried to write similiar callback as you did.
This certainly makes sense for no Output specified but I think there could still be trouble if an Output is specified without MATCH. In the below example if, for whatever reason, the set of input triggers all occur at once (for instance from an Output({"id": ALL, "type": "store"}, "data") event), which callback writes to children of the notification container?
Plotly team, where are you on this, this issue has been around for almost two years now.
To those waiting on a solution: pattern matching works with ALL for clickable inputs, but doesn't with MATCH. There is workaround with ALL:
@callback(Output("notifications_container", "children"),Input({"id": ALL, ...}, "n_clicks"),prevent_initial_call=True)defcb(n_clicks):
# This only needed for preventing the initial trigger, which does happen despite `prevent_initial_call` being setifnotany(n>0forninn_clicks):
raisePreventUpdate# Use dash.ctx to identify the item fired the callbackifnotctx.triggered_id:
raisePreventUpdatetriggered_item_id=ctx.triggered_id["id"]
...
For now this is on the backlog for the Plotly team as we've been focused on the Dash 3.0.0 release with a set of new changes (component typing, hooks, and more) but looking forward this is an improvement I'd love to tackle -- not to say when it will ship, but it's high on the priority list as we look forward for Dash 🙂
Reacted by Ole Jørgen Brønner and Rafael Bernardelli
Hi Plotly team, for me it's not "a limitation" it's preventing me to scale my application any further, I try to ship as much as possible all-in-one objects and the fact that they cannot interact with "general" element make them completely unusable.
FYI typical use case is having a single dcc.Location in the app that all the all-in-One object need to modify according to what have been selected. I'm facing since this morning a bug that was impossible to detect where I update the url from within and AIO component with:
@callback(Output(ids.url(MATCH), "search"),Input(ids.state(MATCH), "data"),Input(ids.map_state(MATCH), "data"),State(ids.url(MATCH), "id"), )@staticmethoddefupdate_url(nav_data: dict|None, map_data: dict|None, url_id: dict) ->str|NoUpdate:
"""Update the url."""# Skip URL updates for backend pagesif"backend"inurl_id.get("aio_id", ""):
returndash.no_update# early exit if no data is availableifnav_dataisNoneormap_dataisNone:
returndash.no_update# Merge data and create statecombined_data= {**nav_data, **map_data}
state=map_state.GlobalMapState.from_data(combined_data)
returnstate.url_params
For those that are still facing this issue I found a workaround using a little trick: I create a callback with the same input and output I use the set_props fonction inside it to target exact ids and I prevent the update at the end.
fromurllib.parseimporturlencode@callback(Output(ids.map_state(MATCH), "id"),Input(ids.state(MATCH), "data"),)defupdate_url(data: dict|None):
"""Update the url."""set_props("url", {"search": f"?{urlencode(data)}"})
returndash.no_update
Activity
alexcjohnson commentedon Mar 16, 2023
Thanks @milind
@T4rk1n I think "any
MATCHpresent in the inputs must be present in all the outputs too" is another flavor of the restriction "every output can be connected to only one callback" - it's just that these duplicates come from the same function. So in the same way as we do for multiple callback functions we should be able to relax that restriction when the output that's missing aMATCHspecifiesallow_duplicate. Seem reasonable?To make this concrete, I guess we're talking about callbacks that would look like:
T4rk1n commentedon Mar 17, 2023
I think the validation should be lifted entirely for Output, it makes
MATCHawkward to use and I remember removing the validation without any breakage.alexcjohnson commentedon Mar 17, 2023
It would have exactly the same kind of breakage scenarios as other duplicate outputs, an ambiguity when two callbacks result from the same stimulus. Which is why I think allowing it the same way (with
allow_duplicate) makes most sense.olejorgenb commentedon Sep 14, 2023
I would also like this restriction to be lifted. I'm trying out a convention where callbacks which modify database state triggers a re-render using a "trigger" output. This does not work with this restriction in place.
For searchability - this is the error message:
Someone else mentioned that they would like to do partial update based on a MATCH callback. On the surface this also sounds like a reasonable use-case (with the disclaimer that I haven't used partial update enough to really know it makes sense).
EDIT: Thinking a bit further - any scenerio where doing something to a component[1] should trigger a not-local-to-that-component update become cumbersome to implement. Only workaround (other than the one mentioned by OP) I can see is to add dummy outputs per component and route these to the callback implementing the global update.
[1] Which there can be an arbitrary number of
RenaudLN commentedon Nov 2, 2023
A current workaround to avoid the network cost of passing ALL to the callback would be:
Something like:
pitris90 commentedon Feb 7, 2024
I would appreciate this restriction lifted too, as it would simplify my callbacks. I was so surprised it doesnt work when I tried to write similiar callback as you did.
wilecoyote2015 commentedon Feb 20, 2024
I second the request, as this limitation if often problematic for our use cases.
alvarodemig commentedon Mar 6, 2024
I agree. The current behavior is counterintuitive, as you can have the same output in multiple callbacks, and this would simplify many patterns.
mmarfat commentedon Apr 3, 2024
Any updates on this?
lunathanael commentedon Apr 16, 2024
Any updates on this?
ndrezn commentedon Apr 21, 2024
Plotly team is looking into this as part of a future Dash release!
deadkex commentedon May 15, 2024
Another example use case:
4 remaining items
mbworth commentedon Oct 31, 2024
This certainly makes sense for no Output specified but I think there could still be trouble if an Output is specified without MATCH. In the below example if, for whatever reason, the set of input triggers all occur at once (for instance from an
Output({"id": ALL, "type": "store"}, "data")event), which callback writes to children of the notification container?vhorvath commentedon Jan 28, 2025
Plotly team, where are you on this, this issue has been around for almost two years now.
To those waiting on a solution: pattern matching works with
ALLfor clickable inputs, but doesn't withMATCH. There is workaround withALL:ndrezn commentedon Jan 28, 2025
For now this is on the backlog for the Plotly team as we've been focused on the Dash 3.0.0 release with a set of new changes (component typing, hooks, and more) but looking forward this is an improvement I'd love to tackle -- not to say when it will ship, but it's high on the priority list as we look forward for Dash 🙂
12rambau commentedon Dec 12, 2025
Hi Plotly team, for me it's not "a limitation" it's preventing me to scale my application any further, I try to ship as much as possible all-in-one objects and the fact that they cannot interact with "general" element make them completely unusable.
12rambau commentedon Jan 15, 2026
FYI typical use case is having a single
dcc.Locationin the app that all the all-in-One object need to modify according to what have been selected. I'm facing since this morning a bug that was impossible to detect where I update the url from within and AIO component with:But it never triggers the global :
becasue they are not pointing to the same Location input, even though visually there is obviously only 1 single url in my browser.
12rambau commentedon Mar 29, 2026
For those that are still facing this issue I found a workaround using a little trick: I create a callback with the same input and output I use the
set_propsfonction inside it to target exact ids and I prevent the update at the end.style: run black and prettier on the new #2462 tests
Merge pull request #3756 from plotly/fix-2462-match-semantics
renderer: relax MATCH wildcard validation when Outputs lack MATCH
renderer: uniquify callback resolvedId per MATCH trigger
tests(integration): exercise MATCH Input with fixed/no Output
docs: changelog entry for plotly#2462 MATCH relaxation
tests: scope to the two plotly#2462 cases per reviewer feedback