{"record":{"id":"4902481e6e6bf3c4","repo":"wtfutil/wtf","slug":"no-table-structure-returned-from-query","errorCode":null,"errorMessage":"no table structure returned from query","messagePattern":"no table structure returned from query","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"modules/azurelogs/widget.go","lineNumber":79,"sourceCode":"/* -------------------- Helper Functions -------------------- */\n\nfunc (widget *Widget) fetchDataAsync() {\n\tsess, err := Init(to.Ptr(widget.settings.Queryfile))\n\tif err != nil {\n\t\twidget.setError(fmt.Errorf(\"failed to initialize Azure session: %w\", err))\n\t\treturn\n\t}\n\n\t// Execute Azure query directly\n\ttableResp, err := RunQuery(sess)\n\tif err != nil {\n\t\twidget.setError(fmt.Errorf(\"failed to execute Azure query: %w\", err))\n\t\treturn\n\t}\n\n\t// Check if we have valid data structure\n\tif tableResp == nil || len(tableResp.Header) == 0 {\n\t\twidget.setError(fmt.Errorf(\"no table structure returned from query\"))\n\t\treturn\n\t}\n\n\t// Store the data and mark as loaded\n\twidget.tableData = tableResp\n\twidget.dataLoaded = true\n\twidget.loading = false\n\twidget.Redraw(widget.content)\n}\n\n// setError is a helper function to set error state and trigger redraw\nfunc (widget *Widget) setError(err error) {\n\twidget.lastError = err\n\twidget.loading = false\n\twidget.Redraw(widget.content)\n}\n\nfunc (widget *Widget) renderTable(title string) (string, string, bool) {","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/wtfutil/wtf/blob/bb838c1ccb0f0f3223690df44afdec663d622881/modules/azurelogs/widget.go#L61-L97","documentation":"After RunQuery succeeds, fetchDataAsync validates the response: if the table response is nil or has no Header columns, it reports 'no table structure returned from query'. This guards against rendering an empty/malformed Log Analytics payload rather than an actual query failure.","triggerScenarios":"RunQuery returns a non-nil *tableResp whose Header slice is empty (len(tableResp.Header)==0), or returns nil with a nil error — e.g. the KQL query matched no data or returned a degenerate table.","commonSituations":"KQL query with zero matching rows producing an empty schema; restrictive RBAC returning empty results; Azure API changes or projection that drops all columns; querying a table that doesn't exist in the workspace.","solutions":["Verify the query returns at least one column (test in Azure portal Log Analytics)","Check the queried table exists in the selected workspace and RBAC permits reading it","Add a default column or '| project' clause so an empty result still has a schema"],"exampleFix":"// before\nlet q = \"Heartbeat | where TimeGenerated > ago(1h) and Computer == 'nonexistent'\"\n// returns zero rows / degenerate table\n// after\nlet q = \"Heartbeat | where TimeGenerated > ago(1h) | project TimeGenerated, Computer | take 10\"\n// always yields a defined column set","handlingStrategy":"validation","validationCode":"func hasTableStructure(t *TableResponse) bool {\n    return t != nil && len(t.Header) > 0\n}\nif !hasTableStructure(tableResp) {\n    widget.setError(errors.New(\"no table structure returned from query\"))\n    return\n}","typeGuard":"func validTable(t *TableResponse) bool {\n    return t != nil && len(t.Header) > 0\n}","tryCatchPattern":"if !validTable(tableResp) {\n    widget.setError(errors.New(\"no table structure returned from query\"))\n    return\n}","preventionTips":["Write queries with an explicit '| project' clause so a schema always exists","Sanity-check queries against the workspace in the Azure portal","Handle empty-result rendering gracefully in the widget instead of treating it as failure"],"tags":["azure","kusto","empty-result","go"],"backgroundTag":"empty-query-result","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"}