googleapis/mcp-toolbox · error

'filter_expression' must be a string, got %T

Error message

'filter_expression' must be a string, got %T

What it means

ProcessQueryArgs validates that the optional 'filter_expression' parameter is a string (Looker expects the Looker filter expression language as text). If the value is present and non-nil but is any other Go type, the function returns this typed error including the offending %T type.

Source

Thrown at internal/tools/looker/lookercommon/lookercommon.go:355

	var tz string
	if paramsMap["tz"] != nil {
		tz = paramsMap["tz"].(string)
	} else {
		tzname, err := tzlocal.RuntimeTZ()
		if err != nil {
			logger.ErrorContext(ctx, fmt.Sprintf("Error getting local timezone: %s", err))
			tzname = "Etc/UTC"
		}
		tz = tzname
	}

	var filterExpressionPtr *string
	if val, ok := paramsMap["filter_expression"]; ok && val != nil {
		if strVal, ok := val.(string); ok {
			filterExpressionPtr = &strVal
		} else {
			return nil, fmt.Errorf("'filter_expression' must be a string, got %T", val)
		}
	}

	var dynamicFieldsPtr *string
	if val, ok := paramsMap["dynamic_fields"]; ok && val != nil {
		if sliceVal, ok := val.([]any); ok && len(sliceVal) > 0 {
			jsonBytes, err := json.Marshal(sliceVal)
			if err != nil {
				return nil, fmt.Errorf("error marshaling dynamic_fields: %w", err)
			}
			jsonStr := string(jsonBytes)
			dynamicFieldsPtr = &jsonStr
		}
	}

	wq := v4.WriteQuery{
		Model:            paramsMap["model"].(string),
		View:             paramsMap["explore"].(string),

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Pass filter_expression as a string, e.g. "users.created_date >= '2024-01-01'"
  2. Serialize structured filters into Looker expression syntax manually before sending
  3. Remove the parameter entirely if no filter expression is needed (it is optional)
  4. Check the %T in the message to see which type was actually sent

Example fix

// before
"filter_expression": {"field": "users.age", "gt": 30}
// after
"filter_expression": "users.age > 30"
Defensive patterns

Strategy: type-guard

Validate before calling

if v, ok := params["filter_expression"]; ok && v != nil {
	if _, ok := v.(string); !ok {
		return fmt.Errorf("filter_expression must be a string")
	}
}

Type guard

func isString(v any) bool { _, ok := v.(string); return ok }

Prevention

When it happens

Trigger: Calling the tool with filter_expression set to a number, bool, array, or object, e.g. filter_expression: 123 or filter_expression: {"field":"x"}.

Common situations: Clients constructing filter expressions as structured JSON objects (as in other BI APIs) instead of Looker expression strings; agents emitting unquoted values; template rendering producing non-string types.

Related errors


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/9d3560ae5b5ac896. Report an issue: GitHub.