googleapis/mcp-toolbox · error

invalid or missing '%s' parameter; expected a string

Error message

invalid or missing '%s' parameter; expected a string

What it means

ValidateAndFetchStoreID extracts the `storeID` parameter from the invocation parameters and asserts it is a string. When the parameter is absent or is not a string (e.g. a number or object), this error is returned. If exactly one store is allowed by the source config, the parameter is not needed at all.

Source

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

const EnablePatientNameFuzzyMatchingKey = "fuzzymatching"

// IncludeAttributesKey is the key used for DICOM search to include additional
// tags in the response.
const IncludeAttributesKey = "includefield"

// ValidateAndFetchStoreID validates the provided storeID against the allowedStores.
// If only one store is allowed, it returns that storeID.
// If multiple stores are allowed, it checks if the storeID parameter is in the allowed list.
func ValidateAndFetchStoreID(params parameters.ParamValues, allowedStores map[string]struct{}) (string, error) {
	if len(allowedStores) == 1 {
		for k := range allowedStores {
			return k, nil
		}
	}
	mapParams := params.AsMap()
	storeID, ok := mapParams[StoreKey].(string)
	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)
			}

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Include a string `storeID` parameter in the tool invocation.
  2. Confirm the store ID exists in the Cloud Healthcare dataset and matches an allowed store if the source pins a list.
  3. Configure the source with a single `allowedStores` entry if the tool should always use one store.
  4. Validate client-side that storeID is a non-empty string before invoking.

Example fix

// before
{"projectId": "p", "location": "us", "datasetId": "d"}   // storeID missing
// after
{"projectId": "p", "location": "us", "datasetId": "d", "storeID": "my-dicom-store"}
Defensive patterns

Strategy: validation

Validate before calling

function validateStoreParams(params) {
  if (typeof params.storeID !== 'string' || params.storeID.length === 0) {
    throw new Error("storeID must be a non-empty string");
  }
  return params;
}
// use: validateStoreParams({storeID: "my-dicom-store", ...})

Type guard

function isStoreID(v) { return typeof v === 'string' && v.length > 0; }

Prevention

When it happens

Trigger: Calling Invoke on a healthcare tool without a `storeID` parameter while the source allows zero or multiple DICOM/FHIR stores, or passing storeID as a non-string (e.g. JSON number).

Common situations: LLM omitting the storeID argument in a tool call; client sending `"storeID": 123` instead of a string; source configured with multiple allowed stores so the parameter becomes required.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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