googleapis/mcp-toolbox · error
model %s returned %d embeddings for %d inputs
Error message
model %s returned %d embeddings for %d inputs
What it means
This sanity check fires when the embedding model returns a different number of vectors than the number of input strings sent. The library requires a strict 1:1 mapping to attach each vector back to its parameter. It almost always indicates a bug or contract violation in the embedding model implementation, not in caller code.
Source
Thrown at internal/util/parameters/parameters.go:224
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 {
stringBatch[i] = paramStr.OriginalValue
}
embeddings, err := model.EmbedParameters(ctx, stringBatch)
if err != nil {
return nil, fmt.Errorf("error embedding parameters with model %s: %w", modelName, err)
}
if len(embeddings) != len(stringBatch) {
return nil, fmt.Errorf("model %s returned %d embeddings for %d inputs", modelName, len(embeddings), len(stringBatch))
}
for i, rawVector := range embeddings {
item := params[i]
// Call vector formatter
var finalValue any = rawVector
if formatter == nil {
paramValues[item.Index].Value = finalValue
continue
}
formattedVector := formatter(rawVector)
finalValue = formattedVector
paramValues[item.Index].Value = finalValue
}View on GitHub (pinned to 8cc6e09de2)
Solutions
- Fix the model's EmbedParameters implementation so it returns exactly one embedding per input or a non-nil error.
- Log the raw provider response to identify which inputs were dropped (e.g. content filtering, empty strings).
- In a paginating wrapper, concatenate every page's results before returning.
- Handle empty or filtered inputs explicitly with a placeholder vector or an error so the result count is preserved.
Example fix
// before: drops failed inputs, breaking 1:1 mapping
out := []vector{}
for _, b := range batch {
v, err := embedOne(b)
if err != nil { continue }
out = append(out, v)
}
// after: error instead of shrinking the result
out := make([]vector, 0, len(batch))
for _, b := range batch {
v, err := embedOne(b)
if err != nil { return nil, err }
out = append(out, v)
} Defensive patterns
Strategy: type-guard
Validate before calling
if got := len(embeddings); got != len(batch) {
return fmt.Errorf("model returned %d embeddings for %d inputs", got, len(batch))
} Type guard
func embeddingsMatchInputs(embeds []Embedding, inputs []string) bool {
return len(embeds) == len(inputs)
} Try / catch
if err != nil {
if strings.Contains(err.Error(), "returned") && strings.Contains(err.Error(), "embeddings") {
// log inputs, flag model implementation bug, skip cache write
}
return err
} Prevention
- For custom embedding models, assert 1:1 input/output counts in the model's own unit tests.
- Never silently drop failed inputs; return an error instead.
- Log the raw provider response when counts diverge to find dropped items.
- Concatenate all pages in paginating wrappers before returning.
When it happens
Trigger: model.EmbedParameters returns a slice whose length differs from len(stringBatch): a custom model implementation silently dropping failed inputs, truncating batches, paginating without concatenating pages, or the provider omitting embeddings for content-filtered inputs.
Common situations: Custom or third-party embedding model wrappers that skip failed items instead of erroring; provider content filtering on some inputs; batch pagination bugs; implementations that deduplicate identical input strings.
Related errors
- embedding model does not exist: %s
- error finding YAML files in %q: %w
- error finding YML files in %q: %w
- failed to initialize resources: %w
- tool %q not found
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/429c6d53786b1e4f.
Report an issue: GitHub.