googleapis/mcp-toolbox · error

unable to prepare statement: %w

Error message

unable to prepare statement: %w

What it means

The Bigtable client's PrepareStatement failed while compiling the SQL statement with the computed parameter type map. Bigtable SQL (via the client library) rejects statements it cannot parse or whose parameter placeholders don't match the declared types. The error is wrapped so the underlying gRPC/API error names the exact problem.

Source

Thrown at internal/sources/bigtable/bigtable.go:180

		}
		btParamTypes[p.GetName()] = paramType
	}
	return btParamTypes, nil
}

func (s *Source) RunSQL(ctx context.Context, statement string, configParam parameters.Parameters, params parameters.ParamValues) (any, error) {
	mapParamsType, err := getMapParamsType(configParam)
	if err != nil {
		return nil, fmt.Errorf("fail to get map params: %w", err)
	}

	ps, err := s.BigtableClient().PrepareStatement(
		ctx,
		statement,
		mapParamsType,
	)
	if err != nil {
		return nil, fmt.Errorf("unable to prepare statement: %w", err)
	}

	bs, err := ps.Bind(params.AsMap())
	if err != nil {
		return nil, fmt.Errorf("unable to bind: %w", err)
	}

	out := []any{}
	var rowErr error
	err = bs.Execute(ctx, func(resultRow bigtable.ResultRow) bool {
		vMap := make(map[string]any)
		cols := resultRow.Metadata.Columns

		for _, c := range cols {
			var columValue any
			if err = resultRow.GetByName(c.Name, &columValue); err != nil {
				rowErr = err
				return false

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Inspect the wrapped underlying error for the specific Bigtable SQL parse/resolution message
  2. Validate the SQL in Bigtable Studio / `cbt` or another client before putting it in the tool config
  3. Ensure every @placeholder in the statement has a corresponding declared parameter with the same name and a supported type
  4. Simplify unsupported SQL constructs (joins/functions) to those Bigtable SQL supports

Example fix

// before
statement: "SELECT * FROM users WHERE id = ?"
// after (named placeholders matching declared params)
statement: "SELECT * FROM users WHERE id = @user_id"
Defensive patterns

Strategy: validation

Validate before calling

// before running, verify placeholders match declared params
func validatePlaceholders(statement string, declared []string) error {
	re := regexp.MustCompile(`@[A-Za-z_][A-Za-z0-9_]*`)
	found := map[string]bool{}
	for _, m := range re.FindAllString(statement, -1) {
		found[m[1:]] = true
	}
	for name := range found {
		if !slices.Contains(declared, name) {
			return fmt.Errorf("placeholder @%s has no declared parameter", name)
		}
	}
	return nil
}

Try / catch

out, err := src.RunSQL(ctx, statement, cfgParams, values)
if err != nil {
	if strings.Contains(err.Error(), "unable to prepare statement") {
		log.Printf("invalid Bigtable SQL: %v", err) // surface wrapped API message
	}
	return err
}

Prevention

When it happens

Trigger: RunSQL calls s.BigtableClient().PrepareStatement(ctx, statement, mapParamsType); Bigtable returns an error for invalid SQL syntax, unknown tables/columns, mismatched placeholder (@param) names versus the declared type map, or unsupported statement kinds.

Common situations: Typos in SQL or table names; using syntax unsupported by Bigtable SQL (dialect differences vs. other SQL engines); param names in the query not matching the tool's declared parameter names; the tool's statement template producing malformed SQL after rendering.

Related errors


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