googleapis/mcp-toolbox · error

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

Error message

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

What it means

After the array check passes for `includefield`, ConvertAnySliceToTyped attempts to coerce every element to a string. If any element is not a string-convertible value, this wrapped error is returned, aborting parameter parsing for the DICOM search call.

Source

Thrown at internal/tools/cloudhealthcare/common/util.go:70

		if _, ok := allowedStores[storeID]; !ok {
			return "", fmt.Errorf("store ID '%s' is not in the list of allowed stores", storeID)
		}
	}
	return storeID, nil
}

// ParseDICOMSearchParameters extracts the search parameters for various DICOM
// search methods.
func ParseDICOMSearchParameters(params parameters.ParamValues, paramKeys []string) ([]googleapi.CallOption, error) {
	var opts []googleapi.CallOption
	for k, v := range params.AsMap() {
		if k == IncludeAttributesKey {
			if _, ok := v.([]any); !ok {
				return nil, fmt.Errorf("invalid '%s' parameter; expected a string array", k)
			}
			attributeIDsSlice, err := parameters.ConvertAnySliceToTyped(v.([]any), "string")
			if err != nil {
				return nil, fmt.Errorf("can't convert '%s' to array of strings: %s", k, err)
			}
			attributeIDs := attributeIDsSlice.([]string)
			if len(attributeIDs) != 0 {
				opts = append(opts, googleapi.QueryParameter(k, strings.Join(attributeIDs, ",")))
			}
		} else if k == EnablePatientNameFuzzyMatchingKey {
			if _, ok := v.(bool); !ok {
				return nil, fmt.Errorf("invalid '%s' parameter; expected a boolean", k)
			}
			opts = append(opts, googleapi.QueryParameter(k, fmt.Sprintf("%t", v.(bool))))
		} else if slices.Contains(paramKeys, k) {
			if _, ok := v.(string); !ok {
				return nil, fmt.Errorf("invalid '%s' parameter; expected a string", k)
			}
			if v.(string) != "" {
				opts = append(opts, googleapi.QueryParameter(k, v.(string)))
			}
		}

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Make every element of `includefield` a quoted string, e.g. ["00100010"].
  2. Filter out null/undefined entries before sending.
  3. Convert numeric tags to their zero-padded string form client-side.
  4. Inspect the inner ConvertAnySliceToTyped message in the error for the offending element.

Example fix

// before
{"includefield": [1048848]}
// after
{"includefield": ["00100010"]}
Defensive patterns

Strategy: validation

Validate before calling

function coerceTagStrings(arr) {
  return arr.map(x => typeof x === 'string' ? x : String(x).padStart(8, '0'));
}
// then verify: coerced.every(x => /^\d{8}$/.test(x))

Type guard

function isAllStrings(arr) { return Array.isArray(arr) && arr.every(x => typeof x === 'string' && x !== ''); }

Prevention

When it happens

Trigger: `includefield` is an array but contains non-string elements, e.g. [123] or [null, "00100010"].

Common situations: LLM emitting numeric DICOM tags without quoting; mixed-type arrays from dynamic client code; nulls injected into the array.

Related errors


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