SigNoz/signoz · error
ErrCodeDashboardInvalidData
ErrCodeDashboardInvalidData
Error message
invalid dashboard data
What it means
GetWidgetQuery serializes dashboard.Data to JSON and then unmarshals it into an internal dashboardData struct. This first failure means dashboard.Data itself cannot be marshalled to JSON — almost always because Data holds a value with an unsupported type (chan, func, complex number, cyclic reference) or a custom MarshalJSON that errors.
Source
Thrown at pkg/types/dashboardtypes/dashboard.go:349
Widgets []struct {
PanelTypes string `json:"panelTypes"`
Query struct {
Builder struct {
QueryData []map[string]any `json:"queryData"`
QueryFormulas []map[string]any `json:"queryFormulas"`
QueryTraceOperator []map[string]any `json:"queryTraceOperator"`
} `json:"builder"`
ClickhouseSQL []map[string]any `json:"clickhouse_sql"`
PromQL []map[string]any `json:"promql"`
QueryType string `json:"queryType"`
} `json:"query"`
FillGaps bool `json:"fillSpans"`
} `json:"widgets"`
}
dataJSON, err := json.Marshal(dashboard.Data)
if err != nil {
return nil, errors.Wrapf(err, errors.TypeInvalidInput, ErrCodeDashboardInvalidData, "invalid dashboard data")
}
var data dashboardData
err = json.Unmarshal(dataJSON, &data)
if err != nil {
return nil, errors.Wrapf(err, errors.TypeInvalidInput, ErrCodeDashboardInvalidData, "invalid dashboard data")
}
if int(widgetIndex) >= len(data.Widgets) {
return nil, errors.Newf(errors.TypeInvalidInput, ErrCodeDashboardInvalidInput, "widget with index %v doesn't exist", widgetIndex)
}
compositeQueries := []any{}
widgetData := data.Widgets[widgetIndex]
switch widgetData.Query.QueryType {
case "builder":
for _, query := range widgetData.Query.Builder.QueryData {
queryName, ok := query["queryName"].(string)View on GitHub (pinned to 5069bf80b0)
Solutions
- Ensure dashboard.Data contains only JSON-serializable values (maps, slices, strings, numbers, bools)
- If using custom types, implement error-free json.Marshaler on them
- Construct dashboards by decoding from JSON so Data is inherently plain
Example fix
// before
dashboard.Data = map[string]any{"ch": make(chan int)}
// after
dashboard.Data = map[string]any{"widgets": []any{}} Defensive patterns
Strategy: validation
Validate before calling
if _, err := json.Marshal(dashboard.Data); err != nil {
return fmt.Errorf("dashboard.Data not serializable: %w", err)
} Type guard
func dataIsJSONSafe(v any) bool {
enc := json.NewEncoder(io.Discard)
enc.SetDiscard() // or use Marshal
_, err := json.Marshal(v)
return err == nil
} Try / catch
q, err := d.GetWidgetQuery(idx, ...)
if err != nil && strings.Contains(err.Error(), "invalid dashboard data") {
return errors.New("dashboard data is not valid JSON-compatible; re-save the dashboard in the UI")
} Prevention
- Build dashboards from decoded JSON, not native Go structs
- Avoid funcs/chans/cycles inside Data
When it happens
Trigger: Calling GetWidgetQuery (via GetPublicWidgetQueryRange) on a dashboard whose Data field contains unserializable values or a nested type whose MarshalJSON returns an error.
Common situations: Programmatically constructed Dashboard objects (not decoded from JSON) holding Go-native non-serializable fields; custom data types injected into Data by integrations; cyclic structs from builder patterns.
Related errors
- ErrCodeDashboardInvalidWidgetQuery
- CodeLicenseUnavailable
- ErrCodePublicDashboardInvalidInput
- invalid_input
- dashboard_invalid_widget_query
AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28).
Data as JSON: /api/errors/8db43a6be52ccbee.
Report an issue: GitHub.