🚀 Gen 5 of the leading AI app deployment platform launches October 6. Click for the livestream.

Must be a list, not a list of lists

Can someone please explain this ubiquitous error to me – perhaps even point to such documentation as would explain why this is an error at all? And maybe even the way to avoid it?

example (certainly not the only time the error has arisen):

row_2 = html.Div(
    [
        dbc.Row(
            dbc.Col(
                html.Div(
                    className="div-row-2",
                    children=[
                    dbc.Row(
                        [
                            dbc.Col(
                                html.Div(
                                    dropdown_0,
                                    
                                    html.I(className="fa fa-info-circle fa-lg",id="button-info",**{'aria-hidden': 'true'}, children=None),

                                    ),
.
.
.

Hi @blah,

Yeah, that’s not a terribly helpful error message.

If the problem code is not obviously a list of lists, then typically this error is caused by a trailing comma – which turns it into a tuple. There are no tuples in JSON, so it gets translated into a list, which causes the error.

row_2 = html.Div(
    [
        dbc.Row(
            dbc.Col(
                html.Div("Oops - trailing comma will cause this to be a list of lists")
            )
        )
    ]
),

Thank you for responding with good info. In my particular case though, I perhaps am remiss for posting a code example too hastily, for the problem is indeed nested lists and I cannot see why it’s a problem, nor now to reliably circumvent it. It seems I am beating my head against a wall for ignorance of the requirements of the components.

Here is an example straight from the docs (Popover - dbc docs):

import dash_bootstrap_components as dbc
import dash_html_components as html

popover_children = [
    dbc.PopoverHeader("Popover header"),
    dbc.PopoverBody("And here's some amazing content. Cool!"),
]

popovers = html.Div(
    [
      dbc.Button(
            "Click",
            id="click-target",
            color="danger",
            className="mr-1",
            n_clicks=0,
        ),
        
       dbc.Popover(
            popover_children,
            id="click",
            target="click-target",
            trigger="click",
        ),
        
    ]
)

So far, so good. Here’s a more complete example from my project (imports not shown; apologies for all the nesting, but I think it should be included considering the problem at hand); this WORKS:

row_5 = html.Div(
    [
        dbc.Row(
            dbc.Col(
                html.Div(
                    id="div-row-5",
                    className="div-row-5",
                    children=[
                        dbc.Row(

                                dbc.Col(
                                    html.Div(

                                        [
                                            dbc.Button(
                                                "Click",
                                                id="click-target_button",
                                                color="danger",
                                                className="mr-1",
                                                n_clicks=0,
                                            ),

                                            html.Div(
                                                [
                                                  dbc.Popover(
                                                       popover_children,
                                                       id="click",
                                                       target="click-target_button",
                                                       trigger="click",
                                                   ),
                                                ]
                                            )
                                        ]
                                    )
                                ),
                            ),

                        ],
                    ),
                )
            ),
        ]
    )

Below does NOT WORK, and the error follows:

the_popover=dbc.Popover(
   popover_children,
   id="click",
   target="click-target_button",
   trigger="click",
),


row_5 = html.Div(
    [
        dbc.Row(
            dbc.Col(
                html.Div(
                    id="div-row-5",
                    className="div-row-5",
                    children=[
                        dbc.Row(

                                dbc.Col(
                                    html.Div(

                                        [
                                            dbc.Button(
                                                "Click",
                                                id="click-target_button",
                                                color="danger",
                                                className="mr-1",
                                                n_clicks=0,
                                            ),

                                            html.Div(
                                                [ #abstracted popover
                                                  the_popover
                                                ]
                                            )
                                        ]
                                    )
                                ),
                            ),

                        ],
                    ),
                )
            ),
        ]
    )

The error:

The children property of a component is a list of lists, instead of just a list. Check the component that has the following contents, and remove one of the levels of nesting: 
[
  {
    "props": {
      "children": [
        {
          "props": {
            "children": "Popover header"
          },
          "type": "PopoverHeader",
          "namespace": "dash_bootstrap_components"
        },
        {
          "props": {
            "children": "And here's some amazing content. Cool!"
          },
          "type": "PopoverBody",
          "namespace": "dash_bootstrap_components"
        }
      ],
      "id": "click",
      "target": "click-target_button",
      "trigger": "click"
    },
    "type": "Popover",
    "namespace": "dash_bootstrap_components"
  }
]

I grant that, within the html.Div is ‘nested’, the Button and the_popover. Why is this a problem? Even in the verbose, original form from the docs, the Popover(which is already embedded in the popovers list) contains a list (the header and body). Why is that OK?

Finally, it seems the only way to avoid this is to revert to the verbose form which is to lose any benefit of abstraction of the code.

I suppose there is an answer that makes sense. Finding it is the challenge.

Thank you!

Thanks for posting some example code…

Try removing this comma. It’s turning the_popover into a tuple

image

commas! :grimacing:

1 Like

That gives this…

Traceback (most recent call last):
  File "/Users/yadda/blah.py", line 19, in <module>
    from layout.layout import *
  File "/Users/yadda/layout/layout.py", line 347
    id="click",
    ^
SyntaxError: invalid syntax

Wait! On rereading your post, I realized that I deleted the wrong comma!

Employing your suggestion correctly has solved the problem! I was aware of being somewhat less than diligent with comma usage, but I didn’t think an extra one outside of any object would be an issue.

Thank you, you have shown me the path to Code Happiness (in this regard, at least)!

5 Gold Stars for you. Wow!

2 Likes

My oh my, the trailing comma issue :grimacing: Ran into this so many times, so tricky to find!

Perhaps we should have a dedicated page in the docs showing folks how to troubleshoot this…

I’d love to see a simple explanation of the problem – ie what it means that a list become a tuple and why.

[edit] and of course it’s already been done…

I agree :100:
When I first started with Dash, it took me days to figure this out. :woman_facepalming:
And a better error message would be super helpful too.