{"record":{"id":"c495b77142386310","repo":"googleapis/mcp-toolbox","slug":"can-t-convert-pivots-to-array-of-strings-s","errorCode":null,"errorMessage":"can't convert pivots to array of strings: %s","messagePattern":"can't convert pivots to array of strings: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/tools/looker/lookercommon/lookercommon.go","lineNumber":328,"sourceCode":"\t// rather than mutating during iteration, and avoid comparing `any` values\n\t// directly (non-comparable dynamic types like slices would panic).\n\tprocessedFilters := make(map[string]any, len(filters))\n\tfor k, v := range filters {\n\t\tnewKey := k\n\t\tif len(k) >= 2 && (k[0] == '\\'' || k[0] == '\"') && k[0] == k[len(k)-1] {\n\t\t\tnewKey = k[1 : len(k)-1]\n\t\t}\n\t\tnewVal := v\n\t\tif s, ok := v.(string); ok && len(s) >= 2 &&\n\t\t\t(s[0] == '\\'' || s[0] == '\"') && s[0] == s[len(s)-1] {\n\t\t\tnewVal = s[1 : len(s)-1]\n\t\t}\n\t\tprocessedFilters[newKey] = newVal\n\t}\n\tfilters = processedFilters\n\tp, err := parameters.ConvertAnySliceToTyped(paramsMap[\"pivots\"].([]any), \"string\")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"can't convert pivots to array of strings: %s\", err)\n\t}\n\tpivots := p.([]string)\n\ts, err := parameters.ConvertAnySliceToTyped(paramsMap[\"sorts\"].([]any), \"string\")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"can't convert sorts to array of strings: %s\", err)\n\t}\n\tsorts := s.([]string)\n\tlimit := fmt.Sprintf(\"%v\", paramsMap[\"limit\"].(int))\n\n\tvar tz string\n\tif paramsMap[\"tz\"] != nil {\n\t\ttz = paramsMap[\"tz\"].(string)\n\t} else {\n\t\ttzname, err := tzlocal.RuntimeTZ()\n\t\tif err != nil {\n\t\t\tlogger.ErrorContext(ctx, fmt.Sprintf(\"Error getting local timezone: %s\", err))\n\t\t\ttzname = \"Etc/UTC\"\n\t\t}","sourceCodeStart":310,"sourceCodeEnd":346,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/tools/looker/lookercommon/lookercommon.go#L310-L346","documentation":"ProcessQueryArgs converts the raw 'pivots' parameter (declared as []any) into a []string via parameters.ConvertAnySliceToTyped. When any element in the pivots slice cannot be converted to a string (e.g. it is a number, bool, map, or nil), the helper returns an error and this wrapper wraps it. It aborts building the Looker run-inline-query request body.","triggerScenarios":"Calling a Looker query tool (e.g. invoke run_inline_query style tools) with pivots supplied as non-string values, such as pivots: [1, 2] or pivots: [{\"field\": \"x\"}], or pivots not being an array at all (the paramsMap[\"pivots\"].([]any) assertion would panic separately).","commonSituations":"LLM/agent clients filling parameters from JSON supply numeric or object values instead of field-name strings; hand-written configs quoting pivots inconsistently; schemas that accept free-form arrays letting wrong types slip through.","solutions":["Ensure every element of the pivots parameter is a JSON string (view/field names), e.g. [\"users.city\",\"orders.count\"]","Check the tool's parameter schema and send pivots as an array, not an object or scalar","If building parameters programmatically, convert values with fmt.Sprintf(\"%v\", v) before passing","Update the calling client so it respects the declared array-of-strings parameter type"],"exampleFix":"// before\n\"pivots\": [1, 2]\n// after\n\"pivots\": [\"users.state\", \"orders.status\"]","handlingStrategy":"validation","validationCode":"func validPivots(v any) bool {\n\ts, ok := v.([]any)\n\tif !ok { return false }\n\tfor _, e := range s {\n\t\tif _, ok := e.(string); !ok { return false }\n\t}\n\treturn true\n}","typeGuard":"if p, ok := params[\"pivots\"].([]any); ok && allStrings(p) { /* safe */ }","tryCatchPattern":null,"preventionTips":["Always send pivots as an array of strings","Validate tool parameters against the schema client-side before invoking","Use the type guard before building the request map"],"tags":["looker","type-conversion","parameters"],"backgroundTag":"parameter-type-mismatch","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}