Callback using pattern matching throws error if there are elements that match the pattern(?)

Hello, I have created as minimal of an example as I can. The title is confusing because as far as I can tell the error I am actually getting is not caused by a singular issue, considering there are multiple posts with this error that have different issues. (Although none of them seem to have an actual solution posted either…)

How do I fix this?

Error: An object was provided as `children` instead of a component, string, or number (or list of those). Check the children property that looks something like:
  "0": {
    "props": {
      "children": "Delete",
      "id": {
        "index": 1,
        "type": "Delete"
      "className": "delete",
      "n_clicks": 0
    "type": "Button",
    "namespace": "dash_html_components"

    at validateComponent (

    at BaseTreeContainer.getComponent (

    at BaseTreeContainer.render (

    at finishClassComponent (

    at updateClassComponent (

    at beginWork (

    at HTMLUnknownElement.callCallback (

    at Object.invokeGuardedCallbackDev (

    at invokeGuardedCallback (

    at beginWork$1 (

The example I have created is here. Note the annotations because they are probably more helpful than the title.

I am running Dash version 2.11.1, on Windows.

from dash import Dash, html, Output, State, Input, Patch, ALL, ctx

app = Dash(__name__)
server = app.server

layout = html.Div([html.Button("Add", id="add", n_clicks=0), html.Div(id="my-div")])

    Output("my-div", "children", allow_duplicate=True),
    Input("add", "n_clicks"),
def add_row(button_clicked):
    # The error is only thrown when the Add button is clicked and presumably when this callback is run.

    patched_list = Patch()

    def new_row():
        return html.Button(
            id={"index": button_clicked, "type": "Delete"}, # When ID is removed no error is thrown

    return patched_list

    Output("my-div", "children", allow_duplicate=True),
    Input({"index": ALL, "type": "Delete"}, "n_clicks"),
    State({"index": ALL, "type": "Delete"}, "id"),
def delete_row(n_clicks, id):
    # When this callback is missing no error is thrown.

    patched_list = Patch()
    triggered_id = ctx.triggered_id

    del patched_list[triggered_id]

    return patched_list

if __name__ == "__main__":
    app.layout = layout
    app.run_server(debug=True, use_reloader=True)

I combined two separate examples on the pattern-matching callbacks page so I have no idea if I did it correctly.


@RGasque Hello!

I believe id in html.Button() (what you are returning) should be a string, not a dictionary. If you need to specify a type, then you may do so using the type parameter (also a string). You might want to review the documentation for more details.

@trlemon Thanks.
Is there a different element I should be using than Button for pattern-matching callbacks? The documentation doesn’t seem to have anything else listed.

@trlemon I don’t think the documentation ever states id can be a dictionary despite it being a feature present in multiple tutorials and examples in the documentation.

@RGasque I’ll have to play around with your example a little more. I’m stumped for now.


This is the page with the examples I based my solution on.

Hi, what are you trying to do with the Patch()?

Are you trying to delete the Buttons?

Side note: If you are using pattern matching callbacks, the triggered_id is a dictionary, with the keys ìndex and type`

If I understand you correctly, you are interested in the index:

triggered_index = ctx.triggered_id.index

Hello @AIMPED, thank you for answering and sorry for responding so late! That was indeed what was causing the error, but it still does not do what I want. I am trying to use the Patch to delete rows of a table, I think my minimal example was in fact too minimal to be practical.

I have solved it, in a way that makes me feel stupid because I should have just copied the example the entire time D:

@app.callback(Output('my-div', 'children', allow_duplicate=True),
              Input({"index": ALL, "type": "Delete"}, 'n_clicks'),
def delete_row(n_clicks):
    patched_list = Patch()
    values_to_remove = []
    for i, val in enumerate(n_clicks):
        if val > 0:
            values_to_remove.insert(0, i)
    for v in values_to_remove:
        del patched_list[v]
    return patched_list
    # This is verbatim the example at the bottom of the pattern matching callbacks page, other than the check being an inequality rather than a truthy check

Always overthink things… Thanks everyone for helping nonetheless. Although I don’t think this is very efficient, I am working with human input here so it should have no impact.

1 Like