googleapis/mcp-toolbox · error

unable to execute client: %w

Error message

unable to execute client: %w

What it means

The bound statement's Execute call — which runs the query over gRPC and streams ResultRows — returned an error. This is the actual query-execution failure point: network/timeout issues, permission denials, invalid query at execution time, or server-side errors mid-stream. The row callback returning false (rowErr path) does NOT trigger this; only the Execute return value does.

Source

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

	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
			}
			vMap[c.Name] = columValue
		}

		out = append(out, vMap)

		return true
	})
	if err != nil {
		return nil, fmt.Errorf("unable to execute client: %w", err)
	}
	if rowErr != nil {
		return nil, fmt.Errorf("error processing row: %w", rowErr)
	}

	return out, nil
}

func initBigtableClient(ctx context.Context, tracer trace.Tracer, name, project, instance string) (*bigtable.Client, error) {
	//nolint:all // Reassigned ctx
	ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name)
	defer span.End()

	// Set up Bigtable data operations client.
	poolSize := 10
	userAgent, err := util.UserAgentFromContext(ctx)
	if err != nil {
		return nil, err

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Inspect the wrapped gRPC error code (permission-denied, deadline-exceeded, unavailable, etc.) and address specifically
  2. Verify the service account has Bigtable read IAM roles on the instance
  3. Increase the request timeout / context deadline for large queries
  4. Retry on transient codes (unavailable/deadline-exceeded) with backoff

Example fix

// before
ctx := context.Background()
// after
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
Defensive patterns

Strategy: retry

Validate before calling

// preflight IAM check
func canQueryBigtable(ctx context.Context, admin *bigtable.AdminClient, table string) error {
	_, err := admin.TableInfo(ctx, table)
	return err // permission-denied surfaces before the query runs
}

Try / catch

out, err := src.RunSQL(ctx, stmt, cfgParams, values)
if err != nil {
	if strings.Contains(err.Error(), "unable to execute client") {
		if isTransient(err) { // codes.Unavailable, DeadlineExceeded
			return retryWithBackoff(ctx, 3, func() error { return runQuery(ctx) })
		}
	}
	return err
}

Prevention

When it happens

Trigger: bs.Execute(ctx, callback) returns non-nil: gRPC error, deadline exceeded, permission denied on the Bigtable instance, query rejected by the server, or stream interrupted mid-read.

Common situations: Deadlines exceeded on large scans; missing IAM roles (bigtable.tables.readRows / bigtable.tables.getData); instance unavailable or quota exceeded; transient network partition between toolbox and Bigtable.

Related errors


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