{"record":{"id":"561508ec6ed98111","repo":"googleapis/mcp-toolbox","slug":"invalid-s-parameter-expected-a-string-array","errorCode":null,"errorMessage":"invalid '%s' parameter; expected a string array","messagePattern":"invalid '(.+?)' parameter; expected a string array","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/tools/cloudhealthcare/common/util.go","lineNumber":66,"sourceCode":"\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"invalid or missing '%s' parameter; expected a string\", StoreKey)\n\t}\n\tif len(allowedStores) > 0 {\n\t\tif _, ok := allowedStores[storeID]; !ok {\n\t\t\treturn \"\", fmt.Errorf(\"store ID '%s' is not in the list of allowed stores\", storeID)\n\t\t}\n\t}\n\treturn storeID, nil\n}\n\n// ParseDICOMSearchParameters extracts the search parameters for various DICOM\n// search methods.\nfunc ParseDICOMSearchParameters(params parameters.ParamValues, paramKeys []string) ([]googleapi.CallOption, error) {\n\tvar opts []googleapi.CallOption\n\tfor k, v := range params.AsMap() {\n\t\tif k == IncludeAttributesKey {\n\t\t\tif _, ok := v.([]any); !ok {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid '%s' parameter; expected a string array\", k)\n\t\t\t}\n\t\t\tattributeIDsSlice, err := parameters.ConvertAnySliceToTyped(v.([]any), \"string\")\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"can't convert '%s' to array of strings: %s\", k, err)\n\t\t\t}\n\t\t\tattributeIDs := attributeIDsSlice.([]string)\n\t\t\tif len(attributeIDs) != 0 {\n\t\t\t\topts = append(opts, googleapi.QueryParameter(k, strings.Join(attributeIDs, \",\")))\n\t\t\t}\n\t\t} else if k == EnablePatientNameFuzzyMatchingKey {\n\t\t\tif _, ok := v.(bool); !ok {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid '%s' parameter; expected a boolean\", k)\n\t\t\t}\n\t\t\topts = append(opts, googleapi.QueryParameter(k, fmt.Sprintf(\"%t\", v.(bool))))\n\t\t} else if slices.Contains(paramKeys, k) {\n\t\t\tif _, ok := v.(string); !ok {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid '%s' parameter; expected a string\", k)\n\t\t\t}","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/tools/cloudhealthcare/common/util.go#L48-L84","documentation":"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.","triggerScenarios":"Invoking a DICOM search tool with `includefield` supplied as a plain string (e.g. \"00100010\") or a number instead of an array like [\"00100010\"].","commonSituations":"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.","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."],"exampleFix":"// before\n{\"includefield\": \"00100010,00100020\"}\n// after\n{\"includefield\": [\"00100010\", \"00100020\"]}","handlingStrategy":"type-guard","validationCode":"function normalizeIncludeField(v) {\n  if (typeof v === 'string') v = v.split(',').map(s => s.trim()).filter(Boolean);\n  if (!Array.isArray(v) || !v.every(x => typeof x === 'string')) {\n    throw new Error('includefield must be an array of strings');\n  }\n  return v;\n}","typeGuard":"function isStringArray(v) { return Array.isArray(v) && v.every(x => typeof x === 'string'); }","tryCatchPattern":null,"preventionTips":["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"],"tags":["go","parameter-validation","dicom","type-mismatch"],"backgroundTag":"parameter-type-mismatch","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}