SigNoz/signoz · error

composite query must contain at least one query type

Error message

composite query must contain at least one query type

What it means

CompositeQuery.Validate() requires that at least one of BuilderQueries, ClickHouseQueries, PromQueries, or the legacy Queries field is populated. A composite query with a valid queryType/panelType but zero actual queries is meaningless and rejected.

Source

Thrown at pkg/query-service/model/v3/v3.go:614

func (c *CompositeQuery) Sanitize() {
	if c == nil {
		return
	}
	// remove groupBy for queries with list panel type
	for _, query := range c.BuilderQueries {
		if len(query.GroupBy) > 0 && c.PanelType == PanelTypeList {
			query.GroupBy = []AttributeKey{}
		}
	}
}

func (c *CompositeQuery) Validate() error {
	if c == nil {
		return fmt.Errorf("composite query is required")
	}

	if c.BuilderQueries == nil && c.ClickHouseQueries == nil && c.PromQueries == nil && len(c.Queries) == 0 {
		return fmt.Errorf("composite query must contain at least one query type")
	}

	if c.QueryType == QueryTypeBuilder {
		for name, query := range c.BuilderQueries {
			if err := query.Validate(c.PanelType); err != nil {
				return fmt.Errorf("builder query %s is invalid: %w", name, err)
			}
		}
	}

	if c.QueryType == QueryTypeClickHouseSQL {
		for name, query := range c.ClickHouseQueries {
			if err := query.Validate(); err != nil {
				return fmt.Errorf("clickhouse query %s is invalid: %w", name, err)
			}
		}
	}

View on GitHub (pinned to 5069bf80b0)

Solutions

  1. Include at least one entry in builderQueries, clickHouseQueries, promQueries, or queries
  2. Make sure the map matches the queryType (builder→builderQueries, promql→promQueries, clickhouse_sql→clickHouseQueries)
  3. Don't send empty objects like "builderQueries":{} — omit the field or add a real query

Example fix

// before
{"compositeQuery":{"queryType":"builder","panelType":"graph"}}

// after
{"compositeQuery":{"queryType":"builder","panelType":"graph","builderQueries":{"A":{"dataSource":"metrics","queryName":"A","aggregateAttribute":{"key":"system_cpu_load","aggregateOperator":"avg"},"expression":"A"}}}}
Defensive patterns

Strategy: validation

Validate before calling

if len(cq.BuilderQueries) == 0 && len(cq.ClickHouseQueries) == 0 && len(cq.PromQueries) == 0 && len(cq.Queries) == 0 { return errors.New("add at least one query") }

Type guard

func hasAtLeastOneQuery(cq *v3.CompositeQuery) bool { return cq != nil && (len(cq.BuilderQueries) > 0 || len(cq.ClickHouseQueries) > 0 || len(cq.PromQueries) > 0 || len(cq.Queries) > 0) }

Prevention

When it happens

Trigger: Sending compositeQuery with queryType set but all query maps empty/absent — e.g. {"queryType":"builder","panelType":"graph"} with no builderQueries — or all maps present but empty objects.

Common situations: Frontend serializing a query tab before the user writes anything, templating that renders query maps to empty objects, or clients stripping unknown fields (a version skew where the server expects a differently named map).

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28). Data as JSON: /api/errors/ccdc7fe705114d67. Report an issue: GitHub.