apache/superset · error · ValidationError
Not a valid list
Error message
Not a valid list
What it means
SharedLabelsColorsField deserializes the shared-labels color config: it accepts a list of strings (the current format), returns [] when given a dict (legacy backward compatibility), and rejects everything else with 'Not a valid list'. It is a custom marshmallow field on the dashboard schema.
Source
Thrown at superset/dashboards/schemas.py:195
"""
A custom field that accepts either a list of strings or a dictionary.
"""
def _deserialize(
self,
value: Union[list[str], dict[str, str]],
attr: Union[str, None],
data: Union[Mapping[str, Any], None],
**kwargs: dict[str, Any],
) -> list[str]:
if isinstance(value, list):
if all(isinstance(item, str) for item in value):
return value
elif isinstance(value, dict):
# Enforce list (for backward compatibility)
return []
raise ValidationError("Not a valid list")
class DashboardJSONMetadataSchema(Schema):
# native_filter_configuration is for dashboard-native filters
native_filter_configuration = fields.List(fields.Dict(), allow_none=True)
# chart_configuration for now keeps data about cross-filter scoping for charts
chart_configuration = fields.Dict()
# global_chart_configuration keeps data about global cross-filter scoping
# for charts - can be overridden by chart_configuration for each chart
global_chart_configuration = fields.Dict()
chart_customization_config = fields.List(fields.Dict(), allow_none=True)
timed_refresh_immune_slices = fields.List(fields.Integer())
# deprecated wrt dashboard-native filters
filter_scopes = fields.Dict()
expanded_slices = fields.Dict()
expand_all_slices = fields.Boolean()
refresh_frequency = fields.Integer()
# deprecated wrt dashboard-native filtersView on GitHub (pinned to f4587218dd)
Solutions
- Send shared_labels_colors as an array of strings, e.g. ["#00ff00", "#ff0000"].
- If you have a dict from an old export, either drop it (it becomes []) or convert its values to a list of strings yourself.
- Map/validate values client-side: colors.every(c => typeof c === 'string').
Example fix
// before
shared_labels_colors: { "label1": "#00ff00" } // legacy dict, coerced to []
shared_labels_colors: [1, 2] // rejected
// after
shared_labels_colors: ["#00ff00", "#0000ff"] Defensive patterns
Strategy: type-guard
Type guard
function isSharedLabelsColors(v: unknown): v is string[] {
return Array.isArray(v) && v.every(x => typeof x === 'string');
} Prevention
- Always send shared_labels_colors as string[]; convert dicts to [] or to their values.
- Type the field in client models so non-string items fail at compile time.
When it happens
Trigger: PUT/POST /api/v1/dashboard/ with shared_labels_colors set to a non-list/non-dict value: a bare string, a number, null in a disallowed position, or a list containing non-string items (e.g. [1, 2]).
Common situations: API clients building the payload dynamically and passing an object where a list of color strings is expected; list items accidentally numbers; older payloads sending dicts (accepted, silently normalized to []).
Related errors
- JSON not valid
- JSON not valid
- Request is incorrect
- Dashboard %(dashboard_id)s not found
- Dashboard parameters are invalid.
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/0900f18057cec3d9.
Report an issue: GitHub.