{"record":{"id":"3bc4f0ecf230ab7f","repo":"googleapis/mcp-toolbox","slug":"can-t-convert-projectids-to-array-of-strings-w","errorCode":null,"errorMessage":"can't convert projectIds to array of strings: %w","messagePattern":"can't convert projectIds to array of strings: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sources/dataplex/searchcatalog/search_catalog.go","lineNumber":146,"sourceCode":"}\n\n// InvokeSearchCatalog performs the common search catalog logic.\nfunc InvokeSearchCatalog(\n\tctx context.Context,\n\tparamsMap map[string]any,\n\ttokenStr string,\n\tsystemName string,\n\tparentParamName string,\n\ttypeMap map[string]string,\n\tprojectID string,\n\tgetCatalogClient func(ctx context.Context, token string) (*dataplexapi.CatalogClient, error),\n) ([]DataplexSearchResponse, error) {\n\tpageSize := int32(paramsMap[\"pageSize\"].(int))\n\tprompt, _ := paramsMap[\"prompt\"].(string)\n\n\tprojectIdSlice, err := parameters.ConvertAnySliceToTyped(paramsMap[\"projectIds\"].([]any), \"string\")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"can't convert projectIds to array of strings: %w\", err)\n\t}\n\tprojectIds := projectIdSlice.([]string)\n\n\tparentIdSlice, err := parameters.ConvertAnySliceToTyped(paramsMap[parentParamName].([]any), \"string\")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"can't convert %s to array of strings: %w\", parentParamName, err)\n\t}\n\tparentIds := parentIdSlice.([]string)\n\n\ttypesSlice, err := parameters.ConvertAnySliceToTyped(paramsMap[\"types\"].([]any), \"string\")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"can't convert types to array of strings: %w\", err)\n\t}\n\ttypes := typesSlice.([]string)\n\n\tquery := ConstructSearchQuery(prompt, projectIds, parentIds, types, systemName)\n\n\treq := &dataplexpb.SearchEntriesRequest{","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/sources/dataplex/searchcatalog/search_catalog.go#L128-L164","documentation":"InvokeSearchCatalog extracts the projectIds parameter from the tool's parameter map and converts it from []any to []string via parameters.ConvertAnySliceToTyped. If any element is not a string-convertible value, the conversion fails and this wrapped error is returned. It is a parameter-type contract enforcement for the tool schema.","triggerScenarios":"Invoking the search_catalog tool with projectIds containing non-string items (numbers, nulls, nested arrays), or projectIds missing from paramsMap causing a type assertion on nil.","commonSituations":"LLM/agent supplying numeric project numbers instead of project ID strings; client SDK serializing an empty list as null; hand-built MCP requests with wrong-typed JSON.","solutions":["Send projectIds as a JSON array of strings, e.g. [\"my-project\"]","Ensure the field is present even when empty ([] not null)","Coerce numeric project numbers to their string project IDs before calling","Wrap the call and surface the wrapped conversion error to the caller for correction"],"exampleFix":"// before\n{\"projectIds\": [123456789]}\n// after\n{\"projectIds\": [\"my-gcp-project\"]}","handlingStrategy":"validation","validationCode":"func validStringSlice(v any) bool {\n\ts, ok := v.([]any)\n\tif !ok { return false }\n\tfor _, e := range s { if _, ok := e.(string); !ok { return false } }\n\treturn true\n}\n// require paramsMap[\"projectIds\"] to pass validStringSlice","typeGuard":"ids, ok := paramsMap[\"projectIds\"].([]any); if !ok || !allStrings(ids) { ... }","tryCatchPattern":"res, err := searchcatalog.InvokeSearchCatalog(ctx, src, params)\nif err != nil {\n\tif strings.Contains(err.Error(), \"can't convert projectIds\") {\n\t\treturn fmt.Errorf(\"projectIds must be an array of strings: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Always serialize projectIds as [\"project-id\"] strings","Send [] instead of null for empty lists","Validate tool parameters against the manifest schema client-side"],"tags":["dataplex","searchcatalog","parameters","type-conversion"],"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"}