googleapis/mcp-toolbox · error
'model' must be a string, got %T
Error message
'model' must be a string, got %T
What it means
ProcessFieldArgs converts incoming parameter values to a map and asserts 'model' is a Go string. If the raw value has another dynamic type, the assertion fails and this error reports the actual %T type, since downstream Looker SDK calls require string model names.
Source
Thrown at internal/tools/looker/lookercommon/lookercommon.go:175
return parameters.Parameters{
modelParameter,
exploreParameter,
fieldsParameter,
filtersParameter,
pivotsParameter,
sortsParameter,
limitParameter,
tzParameter,
filterExpressionParameter,
dynamicFieldsParameter,
}
}
func ProcessFieldArgs(ctx context.Context, params parameters.ParamValues) (*string, *string, error) {
mapParams := params.AsMap()
model, ok := mapParams["model"].(string)
if !ok {
return nil, nil, fmt.Errorf("'model' must be a string, got %T", mapParams["model"])
}
explore, ok := mapParams["explore"].(string)
if !ok {
return nil, nil, fmt.Errorf("'explore' must be a string, got %T", mapParams["explore"])
}
return &model, &explore, nil
}
// escapeUnquotedParameterValue escapes Looker filter-expression metacharacters
// so the value reaches a type: unquoted parameter without being interpreted as
// a wildcard pattern. Looker treats `_` as a single-character wildcard and `%`
// as a multi-character wildcard, and rejects either inside unquoted-parameter
// values; `,` is the filter-expression value separator; `^` is the escape
// character itself. Already-escaped sequences (`^_`, `^%`, `^,`, `^^`) pass
// through unchanged, which keeps the function idempotent for callers that pass
// pre-escaped forms (e.g. round-tripping `default_filter_value` from the
// explore metadata). Lone metacharacters get a `^` prefix; lone `^` is doubled
// to `^^`. Walking rune-by-rune (not whole-string scanning) means a value withView on GitHub (pinned to 8cc6e09de2)
Solutions
- Send 'model' as a JSON string, e.g. {"model": "ecommerce"}.
- Ensure the parameter is present; do not omit it from the tool call.
- If calling from code, pass a plain Go string rather than an interface value.
Example fix
// before
{"model": 123, "explore": "orders"}
// after
{"model": "ecommerce", "explore": "orders"}
Defensive patterns
Strategy: validation
Validate before calling
// Client-side check before invoking
const model = "ecommerce";
if (typeof model !== "string" || model.length === 0) {
throw new Error("'model' must be a non-empty string");
} Type guard
m, ok := mapParams["model"]
if !ok {
model, isStr := m.(string)
if !isStr {
return fmt.Errorf("model must be string, got %T", m)
}
} Try / catch
model, explore, err := lookercommon.ProcessFieldArgs(ctx, params)
if err != nil {
return nil, util.NewInvalidArgumentError("check 'model' parameter: %v", err)
} Prevention
- Declare 'model' as a required string parameter in the tool manifest so clients send strings.
- Quote model names in JSON payloads; avoid numeric ids.
- Add a request-schema check in your MCP client wrapper.
When it happens
Trigger: Invoke receives params where mapParams["model"] is not a string (nil when the parameter is missing, a float/int from JSON numbers, or an object/array from a malformed request body).
Common situations: Client omitting 'model' or sending it as a number; MCP client serializing parameters with unexpected JSON types; calling the tool programmatically with wrong-typed arguments.
Related errors
- 'explore' must be a string, got %T
- unable to bind: %w
- invalid source for %q tool: source %q is not a compatible ty
- invalid source for %q tool: source %q is not a compatible ty
- can't convert fields to array of strings: %s
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/02d9552645c58c00.
Report an issue: GitHub.