googleapis/mcp-toolbox · error

can't convert projectIds to array of strings: %w

Error message

can't convert projectIds to array of strings: %w

What it means

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.

Source

Thrown at internal/sources/dataplex/searchcatalog/search_catalog.go:146

}

// InvokeSearchCatalog performs the common search catalog logic.
func InvokeSearchCatalog(
	ctx context.Context,
	paramsMap map[string]any,
	tokenStr string,
	systemName string,
	parentParamName string,
	typeMap map[string]string,
	projectID string,
	getCatalogClient func(ctx context.Context, token string) (*dataplexapi.CatalogClient, error),
) ([]DataplexSearchResponse, error) {
	pageSize := int32(paramsMap["pageSize"].(int))
	prompt, _ := paramsMap["prompt"].(string)

	projectIdSlice, err := parameters.ConvertAnySliceToTyped(paramsMap["projectIds"].([]any), "string")
	if err != nil {
		return nil, fmt.Errorf("can't convert projectIds to array of strings: %w", err)
	}
	projectIds := projectIdSlice.([]string)

	parentIdSlice, err := parameters.ConvertAnySliceToTyped(paramsMap[parentParamName].([]any), "string")
	if err != nil {
		return nil, fmt.Errorf("can't convert %s to array of strings: %w", parentParamName, err)
	}
	parentIds := parentIdSlice.([]string)

	typesSlice, err := parameters.ConvertAnySliceToTyped(paramsMap["types"].([]any), "string")
	if err != nil {
		return nil, fmt.Errorf("can't convert types to array of strings: %w", err)
	}
	types := typesSlice.([]string)

	query := ConstructSearchQuery(prompt, projectIds, parentIds, types, systemName)

	req := &dataplexpb.SearchEntriesRequest{

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Send projectIds as a JSON array of strings, e.g. ["my-project"]
  2. Ensure the field is present even when empty ([] not null)
  3. Coerce numeric project numbers to their string project IDs before calling
  4. Wrap the call and surface the wrapped conversion error to the caller for correction

Example fix

// before
{"projectIds": [123456789]}
// after
{"projectIds": ["my-gcp-project"]}
Defensive patterns

Strategy: validation

Validate before calling

func validStringSlice(v any) bool {
	s, ok := v.([]any)
	if !ok { return false }
	for _, e := range s { if _, ok := e.(string); !ok { return false } }
	return true
}
// require paramsMap["projectIds"] to pass validStringSlice

Type guard

ids, ok := paramsMap["projectIds"].([]any); if !ok || !allStrings(ids) { ... }

Try / catch

res, err := searchcatalog.InvokeSearchCatalog(ctx, src, params)
if err != nil {
	if strings.Contains(err.Error(), "can't convert projectIds") {
		return fmt.Errorf("projectIds must be an array of strings: %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/3bc4f0ecf230ab7f. Report an issue: GitHub.