googleapis/mcp-toolbox · error

parameter '%s' is marked for embedding but has a non-string

Error message

parameter '%s' is marked for embedding but has a non-string value (type: %T)

What it means

EmbedParams collects parameters flagged for embedding (vector embedding of text) and requires their values to be strings. If a parameter marked for embedding arrives with a non-string value (number, bool, array, etc.), EmbedParams returns this error naming the parameter and its Go type.

Source

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

	type ParamToEmbed struct {
		OriginalValue string
		Index         int // The index in the original Parameters slice
	}

	// Map: modelName -> list of ParamToEmbed
	parametersToEmbed := make(map[string][]ParamToEmbed)

	for i, p := range ps {
		modelName := p.GetEmbeddedBy()
		if modelName == "" {
			continue
		}

		// Get parameter's value to be embedded
		valueStr, ok := paramValues[i].Value.(string)
		if !ok {
			return nil, fmt.Errorf("parameter '%s' is marked for embedding but has a non-string value (type: %T)", p.GetName(), paramValues[i].Value)
		}

		parametersToEmbed[modelName] = append(parametersToEmbed[modelName], ParamToEmbed{
			OriginalValue: valueStr,
			Index:         i,
		})
	}

	// Batch embedding request sent to each model
	for modelName, params := range parametersToEmbed {
		model, ok := pMgr.GetEmbeddingModel(modelName)
		if !ok {
			return nil, fmt.Errorf("embedding model does not exist: %s", modelName)
		}

		// Extract only the string values for the API call
		stringBatch := make([]string, len(params))
		for i, paramStr := range params {

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Send the embedding parameter as a plain string value
  2. Cast/serialize the value to string on the client before invoking the tool
  3. Remove the embedding flag from parameters that are not free-text, or convert the parameter type to string in the tool config
  4. Validate tool arguments against the manifest before invoking

Example fix

// before
{"id": 42}           // param marked for embedding
// after
{"id": "42"}        // or remove embedding from this param
Defensive patterns

Strategy: type-guard

Validate before calling

func embeddingValuesValid(params []Param, values map[string]any) error {
    for _, p := range params {
        if p.ShouldEmbed {
            if _, ok := values[p.Name].(string); !ok {
                return fmt.Errorf("param %s must be a string", p.Name)
            }
        }
    }
    return nil
}

Type guard

func isEmbeddableString(v any) bool {
    _, ok := v.(string)
    return ok
}

Try / catch

embedded, err := EmbedParams(...)
if err != nil {
    return nil, fmt.Errorf("embedding requires string parameter values: %w", err)
}

Prevention

When it happens

Trigger: Invoking a tool whose config marks a parameter with embedding enabled (embeddingModel set) while the caller supplies a non-string value for that parameter, e.g. an integer instead of text.

Common situations: Clients sending numeric IDs or arrays where free text is expected; agent passing JSON numbers; schema drift after editing a tool config to add embedding to a previously non-string parameter.

Related errors


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