googleapis/mcp-toolbox · error
failed to marshal param to JSON: %w
Error message
failed to marshal param to JSON: %w
What it means
convertParamToJSON is a Go template helper that marshals a parameter value to a JSON-formatted string via json.Marshal. json.Marshal only fails for values it cannot encode — channels, funcs, maps with non-string keys, cyclic structures — so this error indicates a template parameter holds an unmarshalable value.
Source
Thrown at internal/util/parameters/common.go:76
case "boolean":
tempSlice := make([]bool, len(s))
for j, item := range s {
b, ok := item.(bool)
if !ok {
return nil, fmt.Errorf("expected item at index %d to be boolean, got %T", j, item)
}
tempSlice[j] = b
}
typedSlice = tempSlice
}
return typedSlice, nil
}
// convertParamToJSON is a Go template helper function to convert a parameter to JSON formatted string.
func convertParamToJSON(param any) (string, error) {
jsonData, err := json.Marshal(param)
if err != nil {
return "", fmt.Errorf("failed to marshal param to JSON: %w", err)
}
return string(jsonData), nil
}
// PopulateTemplateWithJSON populate a Go template with a custom `json` array formatter
func PopulateTemplateWithJSON(templateName, templateString string, data map[string]any) (string, error) {
return PopulateTemplateWithFunc(templateName, templateString, data, template.FuncMap{
"json": convertParamToJSON,
})
}
// PopulateTemplate populate a Go template with no custom formatters
func PopulateTemplate(templateName, templateString string, data map[string]any) (string, error) {
return PopulateTemplateWithFunc(templateName, templateString, data, nil)
}
// PopulateTemplateWithFunc populate a Go template with provided functions
func PopulateTemplateWithFunc(templateName, templateString string, data map[string]any, funcMap template.FuncMap) (string, error) {View on GitHub (pinned to 8cc6e09de2)
Solutions
- Inspect the parameter map and remove/replace the unmarshalable value (channel, func, cyclic ref)
- Convert custom map key types to string keys before templating
- Ensure parameters originate from decoded request data (JSON-safe types)
- Log the marshalled type (%T) to pinpoint which param fails
Example fix
// before
data["cb"] = func() {} // unmarshalable
result, err := PopulateTemplateWithJSON("t", tmpl, data)
// after
data["cb"] = nil
result, err := PopulateTemplateWithJSON("t", tmpl, data) Defensive patterns
Strategy: validation
Validate before calling
func jsonSafe(v any) error {
_, err := json.Marshal(v)
return err
}
// call jsonSafe(param) for each template data value before templating Type guard
func isJSONMarshalable(v any) bool {
return json.Valid(mustMarshal(v)) || marshalableKind(v)
}
func marshalableKind(v any) bool {
switch v.(type) {
case chan struct{}, func():
return false
}
return true
} Try / catch
out, err := PopulateTemplateWithJSON(name, tmpl, data)
if err != nil {
if strings.Contains(err.Error(), "marshal param to JSON") {
return nil, fmt.Errorf("template parameter not JSON-serializable: %w", err)
}
return nil, err
} Prevention
- Only pass JSON-decoded (JSON-safe) values as template parameters
- Avoid channels, funcs, and cyclic references in template data
- Use string-keyed maps for parameters
When it happens
Trigger: Rendering a SQL/tool template with PopulateTemplate/PopulateTemplateWithJSON where the data map contains e.g. a channel, a function, or a cyclic nested value passed as a parameter.
Common situations: Passing a Go func or channel into template data by mistake; using map[customKey]any with non-basic key types; self-referencing structures built programmatically.
Understand the failure class
Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.
Related errors
- failed to marshal result: %w
- operation finished with error but could not marshal error ob
- failed to unmarshal operation bytes: %w
- failed to marshal request: %w
- failed to unmarshal cluster JSON: %w
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/75cbb9fe742814a8.
Report an issue: GitHub.