googleapis/mcp-toolbox · error
error unmarshalling projection: %s
Error message
error unmarshalling projection: %s
What it means
After the project payload template renders, the result is parsed as MongoDB Extended JSON via bson.UnmarshalExtJSON. If the rendered string is not valid Extended JSON, the tool wraps the failure as 'error unmarshalling projection'. The template rendered fine, but its output is not a valid projection document.
Source
Thrown at internal/tools/mongodb/mongodbfind/mongodbfind.go:162
sort := bson.M{}
for _, p := range sortParameters {
sort[p.GetName()] = paramsMap[p.GetName()]
}
opts = opts.SetSort(sort)
if len(projectPayload) > 0 {
result, err := parameters.PopulateTemplateWithJSON("MongoDBFindProjectString", projectPayload, paramsMap)
if err != nil {
return nil, fmt.Errorf("error populating project payload: %s", err)
}
var projection any
err = bson.UnmarshalExtJSON([]byte(result), false, &projection)
if err != nil {
return nil, fmt.Errorf("error unmarshalling projection: %s", err)
}
opts = opts.SetProjection(projection)
logger.DebugContext(ctx, fmt.Sprintf("Projection is set to %v", projection))
}
if limit > 0 {
opts = opts.SetLimit(limit)
logger.DebugContext(ctx, fmt.Sprintf("Limit is being set to %d", limit))
}
return opts, nil
}
func (t Tool) Invoke(ctx context.Context, s sources.Source, params parameters.ParamValues, accessToken tools.AccessToken) (any, util.ToolboxError) {
source, ok := s.(compatibleSource)
if !ok {
return nil, util.NewClientServerError("source used is not compatible with the tool", http.StatusInternalServerError, nil)
}View on GitHub (pinned to 8cc6e09de2)
Solutions
- Correct the projection JSON in the tool config to valid Extended JSON (e.g. {"name": 1}).
- If injecting values via template, ensure they serialize as JSON primitives.
- Test the rendered output of the template for validity before use.
Example fix
# before
project: '{ name: 1, created_at: $date }'
# after
project: '{ "name": 1, "created_at": { "$date": "{{.params.start}}" } }' Defensive patterns
Strategy: validation
Validate before calling
// Go: pre-validate rendered projection parses
var probe any
if err := bson.UnmarshalExtJSON([]byte(rendered), false, &probe); err != nil {
return fmt.Errorf("invalid projection JSON: %w", err)
} Try / catch
opts, err := getOptions(ctx, sortParams, projectPayload, limit, paramsMap)
if err != nil && strings.Contains(err.Error(), "error unmarshalling projection") {
// fall back to no projection
opts, err = getOptions(ctx, sortParams, "", limit, paramsMap)
} Prevention
- Write projections as strict Extended JSON (quote all keys, use {"$date": ...} style).
- Avoid injecting raw non-JSON values through templates.
- Unit-test the rendered projection string with bson.UnmarshalExtJSON.
When it happens
Trigger: Invoke() with a project payload whose rendered output is invalid Extended JSON — e.g. unquoted keys produced by the template, wrong value types, or stray text after rendering.
Common situations: Using standard JSON with unquoted keys expecting Extended JSON acceptance is fine, but using shell-style Mongo syntax like {name: 1} with invalid characters; template injecting non-JSON values (dates, ObjectIds as strings) incorrectly; missing $-operator prefix typos.
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
Related errors
- error populating project payload: %s
- description is required for tool %q
- invalid source for %q tool: source %q is not a compatible ty
- only one of 'collection' or 'collectionAllowedValues' can be
- description is required for tool %q
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/c1e523b49120b4ee.
Report an issue: GitHub.