{"record":{"id":"d78a3a32753d27d5","repo":"wtfutil/wtf","slug":"query-returned-d-tables-expected-1-s","errorCode":null,"errorMessage":"query returned %d tables, expected 1: %s","messagePattern":"query returned (.+?) tables, expected 1: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/azurelogs/query.go","lineNumber":91,"sourceCode":"\t\t},\n\t\tnil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to execute query on workspace %s: %w\", qf.WorkspaceID, err)\n\t}\n\n\tif res.Error != nil {\n\t\treturn nil, res.Error\n\t}\n\n\tswitch len(res.Tables) {\n\tcase 0:\n\t\treturn nil, fmt.Errorf(\"query returned no data tables: %s\", qf.Query)\n\tcase 1:\n\t\tif len(res.Tables[0].Columns) == 0 {\n\t\t\treturn nil, fmt.Errorf(\"query returned table with no columns: %s\", qf.Query)\n\t\t}\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"query returned %d tables, expected 1: %s\", len(res.Tables), qf.Query)\n\t}\n\n\t// Process each row of data\n\tfor _, row := range res.Tables[0].Rows {\n\t\tvar r TableRow\n\n\t\tfor _, field := range row {\n\t\t\tif field == nil {\n\t\t\t\tr = append(r, \"\")\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Convert all data types to string representation\n\t\t\tswitch v := field.(type) {\n\t\t\tcase string:\n\t\t\t\tr = append(r, v)\n\t\t\tcase float64:\n\t\t\t\tr = append(r, fmt.Sprintf(\"%.0f\", v))","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/wtfutil/wtf/blob/bb838c1ccb0f0f3223690df44afdec663d622881/modules/azurelogs/query.go#L73-L109","documentation":"RunQuery expects exactly one table from the Log Analytics response and throws this when len(res.Tables) > 1. The rendering pipeline (TableRow loop) only processes res.Tables[0], so multiple tables would silently drop data. The query text is appended after the count.","triggerScenarios":"RunQuery or fetchDataAsync with KQL that legitimately produces multiple result tables — e.g. multiple batched statements separated by semicolons where more than one emits output, or `union`-style constructs returning several result sets in batch mode.","commonSituations":"Pasting multi-statement KQL (two SELECT-like statements) into the query file, or using features/API versions that return extra diagnostic tables alongside the main result.","solutions":["Reduce the query file to a single KQL statement that yields one table","If batching is needed, split into separate query files and run each with its own Init/RunQuery","Wrap multi-part logic into one statement using `union` or `materialize(...)` so a single table is returned","Verify the API version in use — some responses include extra tables that older rendering code does not expect"],"exampleFix":"// before (two statements -> two tables)\nAzureActivity | take 10\nSigninLogs | take 10\n// after (single table)\nAzureActivity | take 10 | union (SigninLogs | take 10)  // or split into two query files","handlingStrategy":"validation","validationCode":"// reject multi-statement KQL before running\nif strings.Count(qf.Query, \";\") > 0 && !strings.HasSuffix(strings.TrimSpace(qf.Query), \";\") == false {\n    // count standalone result statements\n}\ntrimmed := strings.TrimSpace(qf.Query)\nif strings.Count(trimmed, \"\\n\") > 0 && strings.Count(strings.ReplaceAll(trimmed, \";\", \"\"), \"| \") == 0 {\n    return errors.New(\"only a single KQL statement returning one table is supported\")\n}","typeGuard":null,"tryCatchPattern":"tables, err := RunQuery(sess)\nif err != nil {\n    if strings.Contains(err.Error(), \"tables, expected 1\") {\n        return fmt.Errorf(\"split the query into one statement per file: %w\", err)\n    }\n    return err\n}","preventionTips":["Keep one KQL statement per query config file","Combine multiple sources with `union` into a single result table","Review query files in PRs to catch pasted multi-statement queries"],"tags":["azure","log-analytics","kql","response-shape"],"backgroundTag":"unexpected-query-result-shape","analyzedSha":"bb838c1ccb0f0f3223690df44afdec663d622881","analyzedAt":"2026-09-03T17:02:45.030Z","contentChangedAt":"2026-09-03T17:02:45.030Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}