googleapis/mcp-toolbox · error
invalid '%s' parameter; expected a string array
Error message
invalid '%s' parameter; expected a string array
What it means
ParseDICOMSearchParameters expects the `includefield` parameter to arrive as an array (JSON array of attribute IDs). If the value is any other JSON type (string, number, object), the type assertion to []any fails and this error is returned.
Source
Thrown at internal/tools/cloudhealthcare/common/util.go:66
if !ok {
return "", fmt.Errorf("invalid or missing '%s' parameter; expected a string", StoreKey)
}
if len(allowedStores) > 0 {
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)
}View on GitHub (pinned to 8cc6e09de2)
Solutions
- Send `includefield` as a JSON array of strings, e.g. ["00100010"].
- If you have a single value, wrap it: ["<value>"].
- Validate the payload shape before invoking the tool.
- Split any comma-separated string into elements client-side before sending.
Example fix
// before
{"includefield": "00100010,00100020"}
// after
{"includefield": ["00100010", "00100020"]} Defensive patterns
Strategy: type-guard
Validate before calling
function normalizeIncludeField(v) {
if (typeof v === 'string') v = v.split(',').map(s => s.trim()).filter(Boolean);
if (!Array.isArray(v) || !v.every(x => typeof x === 'string')) {
throw new Error('includefield must be an array of strings');
}
return v;
} Type guard
function isStringArray(v) { return Array.isArray(v) && v.every(x => typeof x === 'string'); } Prevention
- Always send DICOM tag arrays as JSON arrays of strings
- Normalize comma-separated input to arrays in client adapters
- Keep a typed request builder for DICOM search parameters
- Add schema validation (JSON Schema) to outgoing tool calls
When it happens
Trigger: Invoking a DICOM search tool with `includefield` supplied as a plain string (e.g. "00100010") or a number instead of an array like ["00100010"].
Common situations: LLM passing a comma-separated string instead of a JSON array; hand-written HTTP clients forgetting the array wrapper; schema drift where the client sends the old singular field.
Related errors
- can't convert '%s' to array of strings: %s
- 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/561508ec6ed98111.
Report an issue: GitHub.