{"record":{"id":"c9f3df441dbceb2d","repo":"googleapis/mcp-toolbox","slug":"can-t-convert-fields-to-array-of-strings-s","errorCode":null,"errorMessage":"can't convert fields to array of strings: %s","messagePattern":"can't convert fields to array of strings: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/tools/looker/lookercommon/lookercommon.go","lineNumber":303,"sourceCode":"\tif err != nil {\n\t\treturn err\n\t}\n\tEscapeFiltersForUnquotedParameters(wq, unquoted)\n\treturn nil\n}\n\nfunc ProcessQueryArgs(ctx context.Context, params parameters.ParamValues) (*v4.WriteQuery, error) {\n\tlogger, err := util.LoggerFromContext(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to get logger from ctx: %s\", err)\n\t}\n\n\tlogger.DebugContext(ctx, \"params = \", params)\n\tparamsMap := params.AsMap()\n\n\tf, err := parameters.ConvertAnySliceToTyped(paramsMap[\"fields\"].([]any), \"string\")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"can't convert fields to array of strings: %s\", err)\n\t}\n\tfields := f.([]string)\n\tfilters := paramsMap[\"filters\"].(map[string]any)\n\t// Strip a single layer of wrapping quotes from keys and string values.\n\t// Values matter for LookML `type: unquoted` parameters, where Looker\n\t// substitutes the value bare into SQL via {% parameter %}. Build a new map\n\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]","sourceCodeStart":285,"sourceCodeEnd":321,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/tools/looker/lookercommon/lookercommon.go#L285-L321","documentation":"ProcessQueryArgs converts the raw 'fields' slice into []string via parameters.ConvertAnySliceToTyped. If any element cannot be coerced to a string (or the slice is empty/malformed), the conversion fails and this error wraps the underlying cause.","triggerScenarios":"The 'fields' parameter contains non-string entries (numbers, objects, nulls) or is not a []any slice at all, so ConvertAnySliceToTyped(\"string\") errors.","commonSituations":"Clients sending fields as numbers (e.g. [1,2]) or nested objects; null elements inside the array; calling the tool programmatically with an untyped/empty slice.","solutions":["Send fields as an array of strings, e.g. {\"fields\": [\"orders.id\", \"orders.status\"]}.","Remove null or non-string elements from the fields array.","Ensure the fields parameter is an array, not a comma-joined string; if your client only supports strings, split it into an array before invoking."],"exampleFix":"// before\n{\"fields\": \"orders.id,orders.status\"}\n// after\n{\"fields\": [\"orders.id\", \"orders.status\"]}\n","handlingStrategy":"validation","validationCode":"// Client-side check before invoking\nif (!Array.isArray(fields) || fields.some(f => typeof f !== \"string\")) {\n    throw new Error(\"'fields' must be an array of strings\");\n}","typeGuard":"raw, _ := paramsMap[\"fields\"]\nslice, isSlice := raw.([]any)\nif !isSlice {\n    return nil, fmt.Errorf(\"fields must be an array, got %T\", raw)\n}\nfor _, v := range slice {\n    if _, ok := v.(string); !ok {\n        return nil, fmt.Errorf(\"fields entries must be strings, got %T\", v)\n    }\n}","tryCatchPattern":"q, err := lookercommon.ProcessQueryArgs(ctx, params)\nif err != nil && strings.Contains(err.Error(), \"can't convert fields\") {\n    return nil, util.NewInvalidArgumentError(\"'fields' must be an array of strings\")\n}","preventionTips":["Always send fields as [\"field_a\", \"field_b\"]; never comma-joined strings or numbers.","Validate array element types in the calling client before invocation.","Keep the tool manifest parameter typed as an array of strings so MCP clients coerce correctly."],"tags":["parameters","type-conversion","looker"],"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"}