googleapis/mcp-toolbox · error

can't convert fields to array of strings: %s

Error message

can't convert fields to array of strings: %s

What it means

ProcessQueryArgs converts the raw 'fields' slice into []string via parameters.ConvertAnySliceToTyped. If any element cannot be coerced to a string (or the slice is empty/malformed), the conversion fails and this error wraps the underlying cause.

Source

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

	if err != nil {
		return err
	}
	EscapeFiltersForUnquotedParameters(wq, unquoted)
	return nil
}

func ProcessQueryArgs(ctx context.Context, params parameters.ParamValues) (*v4.WriteQuery, error) {
	logger, err := util.LoggerFromContext(ctx)
	if err != nil {
		return nil, fmt.Errorf("unable to get logger from ctx: %s", err)
	}

	logger.DebugContext(ctx, "params = ", params)
	paramsMap := params.AsMap()

	f, err := parameters.ConvertAnySliceToTyped(paramsMap["fields"].([]any), "string")
	if err != nil {
		return nil, fmt.Errorf("can't convert fields to array of strings: %s", err)
	}
	fields := f.([]string)
	filters := paramsMap["filters"].(map[string]any)
	// Strip a single layer of wrapping quotes from keys and string values.
	// Values matter for LookML `type: unquoted` parameters, where Looker
	// substitutes the value bare into SQL via {% parameter %}. Build a new map
	// rather than mutating during iteration, and avoid comparing `any` values
	// directly (non-comparable dynamic types like slices would panic).
	processedFilters := make(map[string]any, len(filters))
	for k, v := range filters {
		newKey := k
		if len(k) >= 2 && (k[0] == '\'' || k[0] == '"') && k[0] == k[len(k)-1] {
			newKey = k[1 : len(k)-1]
		}
		newVal := v
		if s, ok := v.(string); ok && len(s) >= 2 &&
			(s[0] == '\'' || s[0] == '"') && s[0] == s[len(s)-1] {
			newVal = s[1 : len(s)-1]

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Send fields as an array of strings, e.g. {"fields": ["orders.id", "orders.status"]}.
  2. Remove null or non-string elements from the fields array.
  3. Ensure the fields parameter is an array, not a comma-joined string; if your client only supports strings, split it into an array before invoking.

Example fix

// before
{"fields": "orders.id,orders.status"}
// after
{"fields": ["orders.id", "orders.status"]}
Defensive patterns

Strategy: validation

Validate before calling

// Client-side check before invoking
if (!Array.isArray(fields) || fields.some(f => typeof f !== "string")) {
    throw new Error("'fields' must be an array of strings");
}

Type guard

raw, _ := paramsMap["fields"]
slice, isSlice := raw.([]any)
if !isSlice {
    return nil, fmt.Errorf("fields must be an array, got %T", raw)
}
for _, v := range slice {
    if _, ok := v.(string); !ok {
        return nil, fmt.Errorf("fields entries must be strings, got %T", v)
    }
}

Try / catch

q, err := lookercommon.ProcessQueryArgs(ctx, params)
if err != nil && strings.Contains(err.Error(), "can't convert fields") {
    return nil, util.NewInvalidArgumentError("'fields' must be an array of strings")
}

Prevention

When it happens

Trigger: The 'fields' parameter contains non-string entries (numbers, objects, nulls) or is not a []any slice at all, so ConvertAnySliceToTyped("string") errors.

Common situations: Clients sending fields as numbers (e.g. [1,2]) or nested objects; null elements inside the array; calling the tool programmatically with an untyped/empty slice.

Related errors


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