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
- Make every element of `includefield` a quoted string, e.g. ["00100010"].
- Filter out null/undefined entries before sending.
- Convert numeric tags to their zero-padded string form client-side.
- 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
- Quote DICOM tag IDs in JSON payloads; never send them as numbers
- Filter null/undefined entries out of attribute arrays
- Zero-pad numeric tags to their 8-digit string form
- Test parameter serialization with representative payloads
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
- invalid '%s' parameter; expected a string array
- invalid '%s' parameter; expected a boolean
- invalid '%s' parameter; expected a string
- invalid source for %q tool: source %q is not a compatible ty
- source is not compatible with the tool
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/f6e1e07523ee9338.
Report an issue: GitHub.