googleapis/mcp-toolbox · error

expected item at index %d to be string, got %T

Error message

expected item at index %d to be string, got %T

What it means

ConvertAnySliceToTyped converts a []any parameter into a typed Go slice (string, int64, float64, or bool) based on the itemType argument. This error is returned when an element of the input slice cannot be asserted to the requested type, i.e. the array passed by the tool caller contained a value of the wrong kind at position j.

Source

Thrown at internal/util/parameters/common.go:33

package parameters

import (
	"bytes"
	"encoding/json"
	"fmt"
	"text/template"
)

// ConvertAnySliceToTyped a []any to typed slice ([]string, []int, []float etc.)
func ConvertAnySliceToTyped(s []any, itemType string) (any, error) {
	var typedSlice any
	switch itemType {
	case "string":
		tempSlice := make([]string, len(s))
		for j, item := range s {
			s, ok := item.(string)
			if !ok {
				return nil, fmt.Errorf("expected item at index %d to be string, got %T", j, item)
			}
			tempSlice[j] = s
		}
		typedSlice = tempSlice
	case "integer":
		tempSlice := make([]int64, len(s))
		for j, item := range s {
			i, ok := item.(int)
			if !ok {
				return nil, fmt.Errorf("expected item at index %d to be integer, got %T", j, item)
			}
			tempSlice[j] = int64(i)
		}
		typedSlice = tempSlice
	case "float":
		tempSlice := make([]float64, len(s))
		for j, item := range s {
			f, ok := item.(float64)

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Fix the client/tool input so every element of the array matches the declared parameter type (strings for 'string', integers for 'integer', etc.)
  2. Check the tool's parameter schema (manifest) and send the array with the correct element type
  3. If values are integers arriving as floats (JSON numbers), convert or declare the parameter as 'integer'/'float' instead of 'string'
  4. Wrap the call and surface the index from the error message to identify the offending array element

Example fix

// before
ConvertAnySliceToTyped([]any{"a", 42}, "string") // fails at index 1
// after
ConvertAnySliceToTyped([]any{"a", "42"}, "string")
Defensive patterns

Strategy: type-guard

Validate before calling

func allStrings(v []any) bool {
    for _, item := range v {
        if _, ok := item.(string); !ok {
            return false
        }
    }
    return true
}

Type guard

func isStringArray(v []any) bool {
    ok := true
    for _, item := range v {
        _, ok = item.(string)
        if !ok {
            return false
        }
    }
    return ok
}

Try / catch

typed, err := ConvertAnySliceToTyped(s, "string")
if err != nil {
    // err names the offending index; return a 400-style client error
    return nil, fmt.Errorf("invalid string array parameter: %w", err)
}

Prevention

When it happens

Trigger: Calling ConvertAnySliceToTyped (directly or via ProcessQueryArgs/ParseDICOMSearchParameters/buildQueryParameters/InvokeSearchCatalog) with itemType="string" while the slice contains e.g. a float64 or bool, typically because a client sent [123] for a string array parameter.

Common situations: LLM-generated tool arguments with heterogeneous arrays; clients sending numbers for string array params (e.g. list of IDs as integers); YAML/JSON configs where quoted values lost their quotes; version changes in how a datasource parses array parameters.

Related errors


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