googleapis/mcp-toolbox · error

missing parameter %s

Error message

missing parameter %s

What it means

GetParams walks the tool's declared Parameters and requires every one to be present in the supplied paramValuesMap; the first missing key aborts with this error. It enforces that every configured parameter receives a value before template rendering or invocation proceeds.

Source

Thrown at internal/util/parameters/parameters.go:272

			if !ok {
				return "", fmt.Errorf("templateParameter only supports string arrays")
			}
			stringValues = append(stringValues, stringVal)
		}
		return strings.Join(stringValues, ", "), nil
	default:
		return "", fmt.Errorf("invalid parameter type, expected array of type string")
	}
}

// GetParams return the ParamValues that are associated with the Parameters.
func GetParams(params Parameters, paramValuesMap map[string]any) (ParamValues, error) {
	resultParamValues := make(ParamValues, 0)
	for _, p := range params {
		k := p.GetName()
		v, ok := paramValuesMap[k]
		if !ok {
			return nil, fmt.Errorf("missing parameter %s", k)
		}
		resultParamValues = append(resultParamValues, ParamValue{Name: k, Value: v})
	}
	return resultParamValues, nil
}

func ResolveTemplateParams(templateParams Parameters, originalStatement string, paramsMap map[string]any) (string, error) {
	templateParamsValues, err := GetParams(templateParams, paramsMap)
	templateParamsMap := templateParamsValues.AsMap()
	if err != nil {
		return "", fmt.Errorf("error getting template params %s", err)
	}

	funcMap := template.FuncMap{
		"array": ConvertArrayParamToString,
	}
	t, err := template.New("statement").Funcs(funcMap).Parse(originalStatement)
	if err != nil {

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Read the parameter name from the error and send a value for it in the request arguments.
  2. Fix key-name mismatches: the client key must exactly equal the parameter's name in the tool config.
  3. Add a default value in the parameter config for values that should be optional.
  4. For auth parameters, ensure the request is authenticated so the library can inject the value.

Example fix

// before: 'limit' missing
tool.Invoke(ctx, map[string]any{"query": "SELECT 1"})

// after
tool.Invoke(ctx, map[string]any{"query": "SELECT 1", "limit": 10})
Defensive patterns

Strategy: validation

Validate before calling

for _, p := range declaredParams {
    if _, ok := args[p.GetName()]; !ok {
        return fmt.Errorf("argument %q is required by this tool", p.GetName())
    }
}

Type guard

func hasAllParams(args map[string]any, params parameters.Parameters) bool {
    for _, p := range params {
        if _, ok := args[p.GetName()]; !ok {
            return false
        }
    }
    return true
}

Try / catch

pv, err := params.GetParams(toolParams, args)
if err != nil {
    var missing string
    if fmt.Sscanf(err.Error(), "missing parameter %s", &missing) == 1 {
        return fmt.Errorf("please provide argument %q", missing)
    }
    return err
}

Prevention

When it happens

Trigger: Invoking a tool with an arguments map that omits a declared parameter: an MCP/HTTP call missing a required field, a renamed config parameter still referenced by old clients, or an auth parameter not populated because the caller is unauthenticated.

Common situations: LLM clients omitting arguments; name mismatches between client keys and config parameter names; optional parameters without defaults that still must be supplied; framework callers building maps programmatically and dropping keys.

Related errors


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