{"record":{"id":"bdba388460d4abd4","repo":"googleapis/mcp-toolbox","slug":"unable-to-bind-w","errorCode":null,"errorMessage":"unable to bind: %w","messagePattern":"unable to bind: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sources/bigtable/bigtable.go","lineNumber":185,"sourceCode":"\nfunc (s *Source) RunSQL(ctx context.Context, statement string, configParam parameters.Parameters, params parameters.ParamValues) (any, error) {\n\tmapParamsType, err := getMapParamsType(configParam)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"fail to get map params: %w\", err)\n\t}\n\n\tps, err := s.BigtableClient().PrepareStatement(\n\t\tctx,\n\t\tstatement,\n\t\tmapParamsType,\n\t)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to prepare statement: %w\", err)\n\t}\n\n\tbs, err := ps.Bind(params.AsMap())\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to bind: %w\", err)\n\t}\n\n\tout := []any{}\n\tvar rowErr error\n\terr = bs.Execute(ctx, func(resultRow bigtable.ResultRow) bool {\n\t\tvMap := make(map[string]any)\n\t\tcols := resultRow.Metadata.Columns\n\n\t\tfor _, c := range cols {\n\t\t\tvar columValue any\n\t\t\tif err = resultRow.GetByName(c.Name, &columValue); err != nil {\n\t\t\t\trowErr = err\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tvMap[c.Name] = columValue\n\t\t}\n\n\t\tout = append(out, vMap)","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/sources/bigtable/bigtable.go#L167-L203","documentation":"ps.Bind(params.AsMap()) failed when converting the runtime-supplied parameter values to the prepared statement's bound form. This happens when the provided values don't match the declared parameter types/count (e.g. string where integer declared, missing or extra params) or a value is of a Go type the client cannot encode.","triggerScenarios":"RunSQL calls ps.Bind(params.AsMap()) with a params map whose keys or value types don't satisfy the prepared statement's declared SQLTypes (from getMapParamsType).","commonSituations":"Client (LLM) supplies a param value of the wrong type at invocation time; tool config expects a param the caller omitted; array param passed a non-array value; auth/instrumentation middleware injecting mismatched param sets.","solutions":["Check the wrapped error for which parameter failed to bind","Ensure the caller supplies every declared parameter with the correct type (string vs integer vs array)","Verify params order/naming matches the tool's declared parameters in tools.yaml","Add explicit type coercion/validation at the tool level (e.g. declare type: integer and validate input before invoke)"],"exampleFix":"// before\n{\"user_id\": \"123\"}   // declared integer\n// after\n{\"user_id\": 123}     // integer matching Int64SQLType","handlingStrategy":"validation","validationCode":"func validateParamValues(declared parameters.Parameters, values map[string]any) error {\n\tfor _, p := range declared {\n\t\tv, ok := values[p.GetName()]\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"missing value for param %q\", p.GetName())\n\t\t}\n\t\tswitch p.GetType() {\n\t\tcase \"integer\":\n\t\t\tif _, ok := v.(int64); !ok && !isIntLike(v) {\n\t\t\t\treturn fmt.Errorf(\"param %q must be integer, got %T\", p.GetName(), v)\n\t\t\t}\n\t\tcase \"string\":\n\t\t\tif _, ok := v.(string); !ok {\n\t\t\t\treturn fmt.Errorf(\"param %q must be string, got %T\", p.GetName(), v)\n\t\t\t}\n\t\tcase \"array\":\n\t\t\tif _, ok := v.([]any); !ok {\n\t\t\t\treturn fmt.Errorf(\"param %q must be array, got %T\", p.GetName(), v)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}","typeGuard":"func isIntLike(v any) bool {\n\tswitch v.(type) {\n\tcase int, int32, int64, float64:\n\t\treturn true\n\t}\n\treturn false\n}","tryCatchPattern":"out, err := src.RunSQL(ctx, stmt, cfgParams, values)\nif err != nil {\n\tif strings.Contains(err.Error(), \"unable to bind\") {\n\t\t// reject the request with a parameter type/count mismatch message\n\t}\n\treturn err\n}","preventionTips":["Enforce declared parameter types at the tool/API boundary before invoking RunSQL","Send integers as JSON numbers (not quoted strings) when a param is declared integer","Always supply every declared parameter; avoid optional params for Bigtable tools","Coerce client input (strings from LLMs) to declared types before binding"],"tags":["bigtable","parameters","binding","type-mismatch"],"backgroundTag":"parameter-binding-failed","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}