wtfutil/wtf · error

query returned no data tables: %s

Error message

query returned no data tables: %s

What it means

After a successful query execution, RunQuery inspects res.Tables. If the Azure Log Analytics response contains zero tables, the library throws this error because the rendered output always expects exactly one table. Note the %s verb interpolates the KQL query text, not an error string.

Source

Thrown at modules/azurelogs/query.go:85

	res, err := client.QueryWorkspace(
		context.Background(),
		qf.WorkspaceID,
		azquery.Body{
			Query: to.Ptr(qf.Query),
		},
		nil)
	if err != nil {
		return nil, fmt.Errorf("failed to execute query on workspace %s: %w", qf.WorkspaceID, err)
	}

	if res.Error != nil {
		return nil, res.Error
	}

	switch len(res.Tables) {
	case 0:
		return nil, fmt.Errorf("query returned no data tables: %s", qf.Query)
	case 1:
		if len(res.Tables[0].Columns) == 0 {
			return nil, fmt.Errorf("query returned table with no columns: %s", qf.Query)
		}
	default:
		return nil, fmt.Errorf("query returned %d tables, expected 1: %s", len(res.Tables), qf.Query)
	}

	// Process each row of data
	for _, row := range res.Tables[0].Rows {
		var r TableRow

		for _, field := range row {
			if field == nil {
				r = append(r, "")
				continue
			}

View on GitHub (pinned to bb838c1ccb)

Solutions

  1. Loosen the KQL query's filters or extend the time range so it returns at least one row
  2. Verify the target table exists in the workspace (AzureActivity, SigninLogs, etc.)
  3. Run the query in the Azure Portal Log Analytics editor to see what it returns
  4. Add defensive handling in the caller for empty result sets if empty results are expected

Example fix

// before
let filtered = AzureActivity | where TimeGenerated > ago(1h) | where OperationName == "Nonexistent"
// after
let filtered = AzureActivity | where TimeGenerated > ago(24h)  // widen window / relax filters
Defensive patterns

Strategy: validation

Validate before calling

// probe the workspace/table before the real query
res, err := client.Query(ctx, workspaceID, azquery.Body{Query: to.Ptr(tableName + " | count")}, nil)
if err != nil || len(res.Tables) == 0 || res.Tables[0].Rows[0][0].(float64) == 0 {
    return errors.New("table empty or missing; adjust filters or time range")
}

Try / catch

tables, err := RunQuery(sess)
if err != nil {
    if strings.Contains(err.Error(), "no data tables") {
        log.Println("query matched no rows; relaxing time range")
        return nil // treat as empty result if acceptable
    }
    return err
}

Prevention

When it happens

Trigger: RunQuery or fetchDataAsync receiving a valid response whose Tables slice is empty — typically when the KQL query produces no result set (e.g. a filter that matches nothing combined with certain operators) or the API returns an empty body.

Common situations: Queries with a WHERE clause matching no rows in the lookback window, querying a table that doesn't exist in the workspace but not erroring, or time-range filters excluding all data.

Related errors


AI-assisted analysis of wtfutil/wtf@bb838c1ccb (2026-09-03). Data as JSON: /api/errors/40bccb69a5f7eeb6. Report an issue: GitHub.