Callback | SchemaLengthValidationError - Expected 7, Received 8 OR A nonexistent object was used in an `Output` of a Dash callback

Based on SO Post

Goal: Append 1 more to Output list.

Updates at bottom of post.


I want to output marker_symbol, from each trace dict, (as line_marker) to a Plot on the localhost front-end. Error occurs because I don’t yet have an Output() for it.

I do have an Input and State for it:

  • Input(self.customisation_tab.line_marker_button.id, 'n_clicks'),
  • State(self.customisation_tab.line_marker.id, 'value').

Note: customisation_tab is part of the Dash webpage.

This functionality, line_marker, is to be a carbon-copy of line_colour.

  • Drop-down list, containing symbols to choose,
  • Button to apply changes.

How might I write an Output() for this?


Input, State, Output code:

@property
def callbacks(self) -> list:
    callbacks = super().callbacks
    callbacks.extend([
        ... # irrelevant methods redacted
        (self.render_graph,
         [Output(self.graph.id, 'figure'),  # Error
          Output(self.colour_string_div.id, 'children'),
          Output(self.data_persisted_flag.id, 'children'),
          Output(self.variables_tab.xaxis_datepicker.id, 'start_date'),
          Output(self.variables_tab.xaxis_datepicker.id, 'end_date'),
          Output(self.variables_tab.yaxis_warning.id, 'children'),
          Output(self.variables_tab.filtered_data_args_div.id, 'children')],  # Error
         [Input(self.initialised_cache_flag.id, 'children'),
          Input(self.location.id, 'href'),
          Input(self.instance_id_div.id, 'children'),
          Input(self.apply_button.id, 'n_clicks'),
          Input(self.next_button.id, 'n_clicks'),
          Input(self.customisation_tab.line_mode.id, 'value'),
          Input(self.customisation_tab.line_width.id, 'value'),
          Input(self.customisation_tab.line_opacity.id, 'value'),
          Input(self.customisation_tab.line_marker_button.id, 'n_clicks'),
          Input(self.customisation_tab.line_colour_button.id, 'n_clicks'),
          Input(self.customisation_tab.error_colour_radioitems.id, 'value'),
          Input(self.customisation_tab.error_colour_dropdown.id, 'value'),
          Input(self.customisation_tab.error_width.id, 'value'),
          Input(self.customisation_tab.title.id, 'value'),
          Input(self.customisation_tab.xaxis_label.id, 'value'),
          Input(self.customisation_tab.line_style.id, 'value'),
          Input(self.customisation_tab.yaxis_label.id, 'value'),
          Input(self.customisation_tab.yaxis2_label.id, 'value'),
          Input(self.customisation_tab.gridlines_checklist.id, 'value'),
          Input(self.customisation_tab.axes_checklist.id, 'value'),
          Input(self.customisation_tab.origin_checklist.id, 'value')],
         [State(self.graph.id, 'figure'),
          State(get_pattern_matching_id(self.filter_tab.filter_panel.methods_radio.id, ALL), 'value'),
          State(get_pattern_matching_id(self.filter_tab.filter_panel.features_dropdown.id, ALL),
                'value'),
          State(get_pattern_matching_id(self.filter_tab.filter_panel.feature_values_dropdown.id, ALL),
                'value'),
          State(get_pattern_matching_id(self.filter_tab.filter_panel.slider.id, ALL), 'value'),
          State(get_pattern_matching_id(self.filter_tab.filter_panel.date_picker.id, ALL), 'start_date'),
          State(get_pattern_matching_id(self.filter_tab.filter_panel.date_picker.id, ALL), 'end_date'),
          State(self.variables_tab.xaxis_dropdown.id, 'value'),
          State(self.variables_tab.counter_checklist.id, 'value'),
          State(self.variables_tab.xaxis_min_input.id, 'value'),
          State(self.variables_tab.xaxis_max_input.id, 'value'),
          State(self.variables_tab.xaxis_datepicker.id, 'start_date'),
          State(self.variables_tab.xaxis_datepicker.id, 'end_date'),
          State(self.variables_tab.yaxis_min_input.id, 'value'),
          State(self.variables_tab.yaxis_max_input.id, 'value'),
          State(self.variables_tab.yaxis2_min_input.id, 'value'),
          State(self.variables_tab.yaxis2_max_input.id, 'value'),
          State(self.variables_tab.yaxis_dropdown.id, 'value'),
          State(self.variables_tab.yaxis2_checklist.id, 'value'),
          State(self.variables_tab.yaxis2_dropdown.id, 'value'),
          State(self.variables_tab.category_checklist.id, 'value'),
          State(self.variables_tab.category_dropdown.id, 'value'),
          State(self.variables_tab.quantile_slider.id, 'value'),
          State(self.variables_tab.groupby_radio.id, 'value'),
          State(self.variables_tab.coerce_checklist.id, 'value'),
          State(self.customisation_tab.line_marker.id, 'value'),
          State(self.customisation_tab.line_colour.id, 'value'),
          State(self.additional_variables_tab.log_transform_checklist.id, 'value'),
          State(self.additional_variables_tab.log_transform_radioitems.id, 'value'),
          State(self.additional_variables_tab.plot_mean.id, 'value'),
          State(self.additional_variables_tab.plot_error.id, 'value'),
          State(self.additional_variables_tab.error_type.id, 'value'),
          State(self.additional_variables_tab.standard_error.id, 'value')])
    ])
    return callbacks

Traceback:

Traceback (most recent call last):
  File "/home/daniel/miniconda3/envs/linechart/lib/python3.9/site-packages/flask/app.py", line 1523, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/daniel/miniconda3/envs/linechart/lib/python3.9/site-packages/flask/app.py", line 1509, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "/home/daniel/miniconda3/envs/linechart/lib/python3.9/site-packages/dash/dash.py", line 1383, in dispatch
    response.set_data(func(*args, outputs_list=outputs_list))
  File "/home/daniel/miniconda3/envs/linechart/lib/python3.9/site-packages/dash/_callback.py", line 166, in add_context
    flat_output_values = flatten_grouping(output_value, output)
  File "/home/daniel/miniconda3/envs/linechart/lib/python3.9/site-packages/dash/_grouping.py", line 34, in flatten_grouping
    validate_grouping(grouping, schema)
  File "/home/daniel/miniconda3/envs/linechart/lib/python3.9/site-packages/dash/_grouping.py", line 214, in validate_grouping
    SchemaLengthValidationError.check(grouping, full_schema, path, len(schema))
  File "/home/daniel/miniconda3/envs/linechart/lib/python3.9/site-packages/dash/_grouping.py", line 183, in check
    raise SchemaLengthValidationError(value, full_schema, path, expected_len)
dash._grouping.SchemaLengthValidationError: Schema: [<Output `graph-with-dropdown.figure`>, <Output `colour-string-div.children`>, <Output `data-persisted-div.children`>, <Output `xaxis-datepicker.start_date`>, <Output `xaxis-datepicker.end_date`>, <Output `yaxis-warning.children`>, <Output `variables-tab-filter-change-div.children`>]
                Path: ()
                Expected length: 7
                Received value of length 8:
                    [Figure({
    'data': [{'error_y': {'color': '#2dd070', 'symmetric': True, 'thickness': 2, 'type': 'data', 'width': 2},
              'line': {'color': '#2dd070', 'dash': 'solid', 'width': 2},
              'marker': {'size': 6, 'symbol': ['circle', 'square-dot']},
              'mode': 'lines+markers',
              'name': '_percent_Tumour',
              'opacity': 0.8,
              'type': 'scatter',
              'x': [2020-06-01 00:00:00, 2020-06-02 00:00:00, 2020-06-03 00:00:00,
                    2020-06-04 00:00:00, 2020-06-05 00:00:00, 2020-06-06 00:00:00,
                    2020-06-07 00:00:00, 2020-06-08 00:00:00, 2020-06-09 00:00:00,
                    2020-06-10 00:00:00, 2020-06-11 00:00:00, 2020-06-12 00:00:00,
                    2020-06-13 00:00:00, 2020-06-14 00:00:00, 2020-06-15 00:00:00,
                    2020-06-16 00:00:00, 2020-06-17 00:00:00, 2020-06-18 00:00:00,
                    2020-06-19 00:00:00, 2020-06-20 00:00:00, 2020-06-21 00:00:00,
                    2020-06-22 00:00:00, 2020-06-23 00:00:00, 2020-06-24 00:00:00,
                    2020-06-25 00:00:00, 2020-06-26 00:00:00, 2020-06-27 00:00:00,
                    2020-06-28 00:00:00, 2020-06-29 00:00:00, 2020-06-30 00:00:00,
                    2020-07-01 00:00:00, 2020-07-02 00:00:00, 2020-07-03 00:00:00,
                    2020-07-04 00:00:00, 2020-07-05 00:00:00, 2020-07-06 00:00:00,
                    2020-07-07 00:00:00, 2020-07-08 00:00:00, 2020-07-09 00:00:00,
                    2020-07-10 00:00:00, 2020-07-11 00:00:00, 2020-07-12 00:00:00,
                    2020-07-13 00:00:00, 2020-07-14 00:00:00, 2020-07-15 00:00:00,
                    2020-07-16 00:00:00, 2020-07-17 00:00:00, 2020-07-18 00:00:00,
                    2020-07-19 00:00:00, 2020-07-20 00:00:00, 2020-07-21 00:00:00,
                    2020-07-22 00:00:00, 2020-07-23 00:00:00, 2020-07-24 00:00:00,
                    2020-07-25 00:00:00, 2020-07-26 00:00:00, 2020-07-27 00:00:00,
                    2020-07-28 00:00:00, 2020-07-29 00:00:00, 2020-07-30 00:00:00],
              'y': [32.69230769230769, 38.333333333333336, 49.23076923076923,
                    53.1578947368421, 47.0, 43.0, 47.35294117647059,
                    61.904761904761905, 44.23076923076923, 57.69230769230769, 52.5,
                    42.5, 45.0, 50.0, 40.294117647058826, 32.857142857142854, 50.0,
                    54.11764705882353, 50.0, 52.5, 38.75, 39.0, 34.54545454545455,
                    39.0, 30.0, 32.5, 42.666666666666664, 45.0, 49.333333333333336,
                    39.285714285714285, 43.1578947368421, 50.65217391304348,
                    36.666666666666664, 66.25, 39.35897435897436,
                    42.333333333333336, 30.0, 63.1578947368421, 37.64705882352941,
                    46.666666666666664, 41.42857142857143, 43.84615384615385,
                    45.16129032258065, 46.0, 44.285714285714285,
                    30.526315789473685, 46.1764705882353, 40.0, 43.125, 45.0,
                    43.57142857142857, 43.5, 56.666666666666664, 34.09090909090909,
                    46.25, 33.57142857142857, 47.5, 49.166666666666664,
                    49.333333333333336, 34.44444444444444],
              'yaxis': 'y'},
             {'error_y': {'color': '#d62728', 'symmetric': True, 'thickness': 2, 'type': 'data', 'width': 2},
              'line': {'color': '#d62728', 'dash': 'solid', 'width': 2},
              'marker': {'size': 6, 'symbol': ['circle', 'square-dot']},
              'mode': 'lines+markers',
              'name': 'Age',
              'opacity': 0.8,
              'type': 'scatter',
              'x': [2020-06-01 00:00:00, 2020-06-02 00:00:00, 2020-06-03 00:00:00,
                    2020-06-04 00:00:00, 2020-06-05 00:00:00, 2020-06-06 00:00:00,
                    2020-06-07 00:00:00, 2020-06-08 00:00:00, 2020-06-09 00:00:00,
                    2020-06-10 00:00:00, 2020-06-11 00:00:00, 2020-06-12 00:00:00,
                    2020-06-13 00:00:00, 2020-06-14 00:00:00, 2020-06-15 00:00:00,
                    2020-06-16 00:00:00, 2020-06-17 00:00:00, 2020-06-18 00:00:00,
                    2020-06-19 00:00:00, 2020-06-20 00:00:00, 2020-06-21 00:00:00,
                    2020-06-22 00:00:00, 2020-06-23 00:00:00, 2020-06-24 00:00:00,
                    2020-06-25 00:00:00, 2020-06-26 00:00:00, 2020-06-27 00:00:00,
                    2020-06-28 00:00:00, 2020-06-29 00:00:00, 2020-06-30 00:00:00,
                    2020-07-01 00:00:00, 2020-07-02 00:00:00, 2020-07-03 00:00:00,
                    2020-07-04 00:00:00, 2020-07-05 00:00:00, 2020-07-06 00:00:00,
                    2020-07-07 00:00:00, 2020-07-08 00:00:00, 2020-07-09 00:00:00,
                    2020-07-10 00:00:00, 2020-07-11 00:00:00, 2020-07-12 00:00:00,
                    2020-07-13 00:00:00, 2020-07-14 00:00:00, 2020-07-15 00:00:00,
                    2020-07-16 00:00:00, 2020-07-17 00:00:00, 2020-07-18 00:00:00,
                    2020-07-19 00:00:00, 2020-07-20 00:00:00, 2020-07-21 00:00:00,
                    2020-07-22 00:00:00, 2020-07-23 00:00:00, 2020-07-24 00:00:00,
                    2020-07-25 00:00:00, 2020-07-26 00:00:00, 2020-07-27 00:00:00,
                    2020-07-28 00:00:00, 2020-07-29 00:00:00, 2020-07-30 00:00:00],
              'y': [75.15384615384616, 53.333333333333336, 80.6923076923077,
                    67.36842105263158, 68.8, 72.1, 64.52941176470588,
                    60.95238095238095, 63.0, 71.84615384615384, 75.125, 47.6, 56.0,
                    46.0, 48.76470588235294, 74.57142857142857, 51.0,
                    73.52941176470588, 77.5, 62.0, 77.0625, 72.5,
                    66.86363636363636, 56.0, 79.2, 80.9, 59.93333333333333,
                    55.888888888888886, 70.2, 66.14285714285714, 63.89473684210526,
                    66.0, 72.55555555555556, 74.0, 54.1025641025641,
                    66.53333333333333, 80.44444444444444, 69.89473684210526,
                    71.58823529411765, 71.66666666666667, 56.142857142857146,
                    47.46153846153846, 72.74193548387096, 78.6, 67.92857142857143,
                    56.26315789473684, 72.29411764705883, 62.81818181818182,
                    63.125, 72.0909090909091, 67.52380952380952, 76.5, 74.0,
                    55.54545454545455, 55.25, 66.28571428571429, 65.0,
                    77.41666666666667, 66.8, 65.66666666666667],
              'yaxis': 'y2'}],
    'layout': {'showlegend': False,
               'template': {},
               'transition': {'duration': 2000, 'easing': 'cubic-in-out'},
               'xaxis': {'range': [None, None],
                         'showgrid': True,
                         'showline': False,
                         'title': {'text': 'Test_DateTime'},
                         'zeroline': False},
               'yaxis': {'range': [None, None],
                         'showgrid': True,
                         'showline': False,
                         'title': {'text': '_percent_Tumour'},
                         'zeroline': False}}
}), ['circle', 'square-dot'], ['#2dd070', '#d62728'], <dash._callback.NoUpdate object at 0x7f73bf594730>, <dash._callback.NoUpdate object at 0x7f73bf594730>, <dash._callback.NoUpdate object at 0x7f73bf594730>, '', '22380905-06ff-4365-b479-a8380a994b7a']

Defining marker_string_div and appending to Output():

callbacks.extend([
        ... # irrelevant methods redacted
        (self.render_graph,
         [Output(self.graph.id, 'figure'),
          Output(self.marker_string_div.id, 'children'), # Appended
          Output(self.colour_string_div.id, 'children'),
...

Immediately errors:

A nonexistent object was used in an `Output` of a Dash callback. The id of this object is `marker-string-div` and the property is `children`. The string ids in the current layout are: [url, page-content, app-title-header, last-modified-header, wrapped-tabs, filter-tab, filter-panel-container, initialise-data-flag-filter, variables-tab, groupby-radio, num2-bool, cat-bool, counter-checklist, xaxis-dropdown, num-dropdown, yaxis-warning, num2-style, num2-dropdown, xaxis-range-style, x-axis-min, x-axis-max, xaxis-datepicker-style, xaxis-datepicker, y-axis-min, y-axis-max, yaxis2-min- range-div, y-axis2-min, yaxis2-max- range-div, y-axis2-max, category-div, cat-dropdown, quantile-slider-style, num-to-cat-checklist, quantile-slider-div, quantile-slider, variables-tab-filter-change-div, variables-tab-load-data-args, additional-variables-tab, log-transform-checklist, log-transform-radioitems, mean-checklist, error-checklist, standard-error, standard-error-checklist, error-bars, error-radioitems, customise-tab, title-input, xaxis-input, yaxis-input, yaxis2-style, yaxis2-input, dash-checklist, mode-dropdown, gridlines-checklist, axes-checklist, origin-checklist, marker-dropdown, marker-button, colour-dropdown, colour-button, width-slider, opacity-slider, error-bar-width-slider, error-colour-radioitems, error-colour_div, error-colour-dropdown, download-tab, csv-tooltip, excel-tooltip, html-tooltip, presigned-url-csv-div, presigned-url-xlsx-div, presigned-url-html-div, download-tab-file-name-input-box, transpose-checklist, download-tab-report-title-input-box, report-notes, optional-data-div, optional-data-checklist, csv-button, excel-button, html-button, save-html-button, update-download-data-flag, reload-data-flag, html-report-div, saved-report-popup, save-report-flag, presigned-url-div, download-div, apply-button, apply-button-tooltip, next-app-style, next-app-button, graph-with-dropdown, colour-string-div, signal-div, instance-id-div, initialised-cache-flag, current-tab-id, step, data-persisted-div, hidden-div]

First, I had to append and return the body_div:

@property
    def body_div(self) -> Div:
        return Div([self.graph, self.marker_string_div])

Because I have tabs all on one page, most components need to appear and disappear. However, I wanted the graph and its markers to always appear in this case.

Lastly (the main part), I had to add this to the Dash app’s Layout. I had written the marker_string_div component, functions, validation, and UI elements. All I need to do was add it to the return line.

1 Like