{"record":{"id":"dba31a6c6ccb3eca","repo":"SigNoz/signoz","slug":"select-columns-cannot-be-empty-for-paneltype-s","errorCode":null,"errorMessage":"select columns cannot be empty for panelType %s","messagePattern":"select columns cannot be empty for panelType (.+?)","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"pkg/query-service/app/traces/v4/query_builder.go","lineNumber":342,"sourceCode":"\t\t\t\tafterSubQuery := tracesV3.AddLimitToQuery(constants.TracesExplorerViewSQLSelectAfterSubQuery, mq.Limit)\n\t\t\t\tif mq.Offset != 0 {\n\t\t\t\t\tafterSubQuery = tracesV3.AddOffsetToQuery(afterSubQuery, mq.Offset)\n\t\t\t\t}\n\t\t\t\tquery = fmt.Sprintf(constants.TracesExplorerViewSQLSelectBeforeSubQuery, constants.SIGNOZ_TRACE_DBNAME, constants.SIGNOZ_SPAN_INDEX_V3, timeFilter, filterSubQuery) + withSubQuery + \")\" + afterSubQuery\n\t\t\t} else {\n\t\t\t\twithSubQueryWithLimits := tracesV3.AddLimitToQuery(constants.TracesExplorerSpanCountWithSubQuery, mq.Limit)\n\t\t\t\twithSubQuery := fmt.Sprintf(withSubQueryWithLimits, constants.SIGNOZ_TRACE_DBNAME, constants.SIGNOZ_SPAN_INDEX_V3_LOCAL_TABLENAME, timeFilter, filterSubQuery)\n\t\t\t\tafterSubQuery := tracesV3.AddLimitToQuery(constants.TraceExplorerSpanCountAfterSubQuery, mq.Limit)\n\t\t\t\tif mq.Offset != 0 {\n\t\t\t\t\tafterSubQuery = tracesV3.AddOffsetToQuery(afterSubQuery, mq.Offset)\n\t\t\t\t}\n\t\t\t\tquery = fmt.Sprintf(constants.TraceExplorerSpanCountBeforeSubQuery, constants.SIGNOZ_TRACE_DBNAME, constants.SIGNOZ_SPAN_INDEX_V3) + withSubQuery + \") \" + fmt.Sprintf(afterSubQuery, constants.SIGNOZ_TRACE_DBNAME, constants.SIGNOZ_SPAN_INDEX_V3, timeFilter)\n\t\t\t}\n\t\t\t// adding this to avoid the distributed product mode error which doesn't allow global in\n\t\t\tquery += \" settings distributed_product_mode='allow', max_memory_usage=10000000000\"\n\t\t} else if panelType == v3.PanelTypeList {\n\t\t\tif len(mq.SelectColumns) == 0 {\n\t\t\t\treturn \"\", fmt.Errorf(\"select columns cannot be empty for panelType %s\", panelType)\n\t\t\t}\n\t\t\tselectLabels = getSelectLabels(mq.SelectColumns)\n\t\t\t// add it to the select labels\n\t\t\tqueryNoOpTmpl := fmt.Sprintf(\"SELECT timestamp as timestamp_datetime, span_id as spanID, trace_id as traceID,%s \", selectLabels) + \"from \" + constants.SIGNOZ_TRACE_DBNAME + \".\" + constants.SIGNOZ_SPAN_INDEX_V3 + \" where %s %s\" + \"%s\"\n\t\t\tquery = fmt.Sprintf(queryNoOpTmpl, timeFilter, filterSubQuery, orderBy)\n\t\t} else {\n\t\t\treturn \"\", fmt.Errorf(\"unsupported aggregate operator %s for panelType %s\", mq.AggregateOperator, panelType)\n\t\t}\n\t\treturn query, nil\n\t\t// ---- NOOP ends here ----\n\t}\n\n\thaving := tracesV3.Having(mq.Having)\n\tif having != \"\" {\n\t\thaving = \" having \" + having\n\t}\n\n\tgroupBy := tracesV3.GroupByAttributeKeyTags(panelType, options.GraphLimitQtype, mq.GroupBy...)","sourceCodeStart":324,"sourceCodeEnd":360,"githubUrl":"https://github.com/SigNoz/signoz/blob/5069bf80b08f1f00d7e014eccc09902f9871004f/pkg/query-service/app/traces/v4/query_builder.go#L324-L360","documentation":"buildTracesQuery (v4) with a no-op aggregate and panelType=list constructs SELECT ... <selectColumns> from the span index; when SelectColumns is empty there is nothing to project besides the fixed columns, so the request is rejected.","triggerScenarios":"Sending a PanelTypeList no-op traces query with an empty or missing mq.SelectColumns array.","commonSituations":"Programmatic list queries that only set filters and forget projections; UI bugs dropping select columns during query serialization.","solutions":["Populate mq.SelectColumns with the attribute keys to display (e.g. service.name, name, duration_ns)","Default to a sensible projection like [service.name, name, responseStatusCode] if the user selected none"],"exampleFix":"// before\nmq.SelectColumns = []v3.AttributeKey{}\n\n// after\nmq.SelectColumns = []v3.AttributeKey{{Key:\"service.name\",DataType:\"string\",Type:\"resource\"}, {Key:\"name\",DataType:\"string\",Type:\"tag\"}}","handlingStrategy":"validation","validationCode":"if panelType == v3.PanelTypeList && mq.AggregateOperator == v3.AggregateOperatorNoOp && len(mq.SelectColumns) == 0 {\n    mq.SelectColumns = []v3.AttributeKey{{Key: \"service.name\", DataType: \"string\", Type: \"resource\"}}\n}","typeGuard":"func hasSelectColumns(mq *v3.BuilderQuery) bool { return len(mq.SelectColumns) > 0 }","tryCatchPattern":null,"preventionTips":["Default select columns in the UI when none chosen","Assert non-empty projections in query tests"],"tags":["signoz","traces","v4","select-columns","validation"],"backgroundTag":"query-validation-failed","analyzedSha":"5069bf80b08f1f00d7e014eccc09902f9871004f","analyzedAt":"2026-08-28T06:22:12.824Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}