{"record":{"id":"e1c45eeb6a816a9c","repo":"SigNoz/signoz","slug":"cannot-join-the-given-group-keys","errorCode":null,"errorMessage":"cannot join the given group keys","messagePattern":"cannot join the given group keys","errorType":"http","errorClass":"model.ApiError","httpStatus":400,"severity":"error","filePath":"pkg/query-service/app/parser.go","lineNumber":827,"sourceCode":"\t\t\t\t\t\t\tgroupKeys[v] = append(groupKeys[v], key.Key)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn nil, &model.ApiError{Typ: model.ErrorBadData, Err: fmt.Errorf(\"unknown variable %s\", v)}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tparams := make(map[string]interface{})\n\t\t\t\tfor k, v := range groupKeys {\n\t\t\t\t\tparams[k] = v\n\t\t\t\t}\n\n\t\t\t\tcan, _, err := expression.CanJoin(params)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}\n\t\t\t\t}\n\n\t\t\t\tif !can {\n\t\t\t\t\treturn nil, &model.ApiError{Typ: model.ErrorBadData, Err: fmt.Errorf(\"cannot join the given group keys\")}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If the step interval is less than the minimum allowed step interval, set it to the minimum allowed step interval\n\t\t\tif minStep := common.MinAllowedStepInterval(queryRangeParams.Start, queryRangeParams.End); query.StepInterval < minStep {\n\t\t\t\tquery.StepInterval = minStep\n\t\t\t}\n\n\t\t\tif query.DataSource == v3.DataSourceMetrics {\n\t\t\t\t// if the time range is greater than 1 day, and less than 1 week set the step interval to be multiple of 5 minutes\n\t\t\t\t// if the time range is greater than 1 week, set the step interval to be multiple of 30 mins\n\t\t\t\tstart, end := queryRangeParams.Start, queryRangeParams.End\n\t\t\t\tif end-start >= 24*time.Hour.Milliseconds() && end-start < 7*24*time.Hour.Milliseconds() {\n\t\t\t\t\tquery.StepInterval = int64(math.Round(float64(query.StepInterval)/300)) * 300\n\t\t\t\t} else if end-start >= 7*24*time.Hour.Milliseconds() {\n\t\t\t\t\tquery.StepInterval = int64(math.Round(float64(query.StepInterval)/1800)) * 1800\n\t\t\t\t}\n\t\t\t}","sourceCodeStart":809,"sourceCodeEnd":845,"githubUrl":"https://github.com/SigNoz/signoz/blob/5069bf80b08f1f00d7e014eccc09902f9871004f/pkg/query-service/app/parser.go#L809-L845","documentation":"For formula (expression) queries, the group-by keys of all referenced queries must be joinable — expression.CanJoin checks compatibility. If group keys don't align (e.g. different groupBy sets that can't be merged), the query is rejected.","triggerScenarios":"Formula 'A + B' where A groups by service_name and B groups by operation_name (disjoint group-bys), producing a non-joinable combination.","commonSituations":"Building a formula over queries with mismatched group-by dimensions in the dashboard UI; modifying groupBy of one query after creating the formula.","solutions":["Align group-by dimensions across all queries used in the expression (use the same groupBy set)","Group at a common coarser dimension present in both queries","Remove the formula or split it into separate panels if the join is semantically invalid"],"exampleFix":"// before\nA: groupBy [service_name]; B: groupBy [operation_name]; expr: A + B\n// after\nA: groupBy [service_name]; B: groupBy [service_name]; expr: A + B","handlingStrategy":"validation","validationCode":"keys := map[string][]string{}\nfor _, v := range vars { keys[v] = groupKeysOf(v) }\nif can, _, err := expression.CanJoin(toParams(keys)); err != nil || !can { return errors.New(\"group-bys are not joinable; align dimensions\") }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use identical groupBy sets for queries combined in formulas","When formulas are needed, prefer single-query formulas or shared dimensions"],"tags":["signoz","query-builder","formula","group-by","join"],"backgroundTag":"group-by-mismatch","analyzedSha":"5069bf80b08f1f00d7e014eccc09902f9871004f","analyzedAt":"2026-08-28T06:22:12.824Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}