SigNoz/signoz · error

builder query %s is invalid: %w

Error message

builder query %s is invalid: %w

What it means

Thrown by CompositeQuery.Validate when a query in the BuilderQueries map fails its own BuilderQuery.Validate for the given panel type. The %s is the map key (query name) and %w wraps the inner validation error explaining the actual problem.

Source

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

		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)
			}
		}
	}

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

View on GitHub (pinned to 5069bf80b0)

Solutions

  1. Inspect the wrapped error (%w) — it names the exact field that failed inside the builder query
  2. Ensure each BuilderQueries entry has QueryName, Expression, and a valid DataSource
  3. Validate the payload client-side with the same rules before sending (e.g. check Expression != "")
  4. Check panel type compatibility (e.g. value panels with group by need SecondaryAggregation)

Example fix

// before
{"queryType":"builder","builderQueries":{"A":{"expression":""}}}
// after
{"queryType":"builder","builderQueries":{"A":{"queryName":"A","expression":"A","dataSource":"metrics"}}}
Defensive patterns

Strategy: validation

Validate before calling

func validBuilderQuery(q v3.BuilderQuery) error {
	if q.QueryName == "" || q.Expression == "" { return errors.New("queryName and expression required") }
	if err := q.DataSource.Validate(); err != nil { return err }
	return nil
}
for name, q := range composite.BuilderQueries {
	if err := validBuilderQuery(q); err != nil { return fmt.Errorf("query %s: %w", name, err) }
}

Type guard

func isSimpleBuilderQuery(q v3.BuilderQuery) bool {
	return q.QueryName != "" && q.Expression != "" && q.DataSource != ""
}

Try / catch

if err := compositeQuery.Validate(); err != nil {
	// err already contains query name; log and map to 400 Bad Request
	http.Error(w, err.Error(), http.StatusBadRequest)
}

Prevention

When it happens

Trigger: POSTing a v3 composite query with queryType=builder where one of the BuilderQueries entries has an empty expression, missing query name, invalid aggregate operator, invalid filters, etc.

Common situations: Building dashboard/chart API payloads by hand, migrating from v2 payloads, formulas referencing misconfigured queries, or UI-generated queries with incomplete builder fields.

Related errors


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