googleapis/mcp-toolbox · error

invalid source for %q tool: source %q is not a compatible ty

Error message

invalid source for %q tool: source %q is not a compatible type

What it means

The Spanner execute-sql tool's ValidateSource checks that the resolved source implements the compatibleSource interface (a Spanner source exposing a *spanner.Client). If the source bound to this tool is a different kind of source (e.g. Postgres, SQLite), the type assertion fails and this error is returned. Tools may only run against sources of the matching engine type.

Source

Thrown at internal/tools/spanner/spannersql/spannersql.go:176

	resp, err := source.RunSQL(ctx, t.Cfg.ReadOnly, newStatement, mapParams)
	if err != nil {
		return nil, util.ProcessGcpError(err)
	}
	return resp, nil
}

func (t Tool) GetSourceName() string {
	return t.Cfg.Source
}

func (t Tool) ToConfig() tools.ToolConfig {
	return t.Cfg
}

func (t Tool) ValidateSource(source sources.Source) error {
	_, ok := source.(compatibleSource)
	if !ok {
		return fmt.Errorf("invalid source for %q tool: source %q is not a compatible type", t.Cfg.Type, t.Cfg.Source)
	}
	return nil
}

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Change the tool's `source:` field in the YAML to the name of a source whose `kind` is `spanner`.
  2. Declare a `sources:` entry of kind `spanner` if none exists, then point the tool at it.
  3. If using multiple sources, verify each tool references the source matching its engine type.
  4. Add a startup config check so source/tool compatibility is validated before serving.

Example fix

# before
sources:
  my-pg:
    kind: postgres
    uri: ...
tools:
  run-query:
    kind: spanner-execute-sql
    source: my-pg
# after
sources:
  my-spanner:
    kind: spanner
    project: my-project
    instance: my-instance
    database: my-db
tools:
  run-query:
    kind: spanner-execute-sql
    source: my-spanner
Defensive patterns

Strategy: type-guard

Validate before calling

# Validate before running:
grep -A2 'kind: spanner' tools.yaml   # confirm a spanner source exists
# and that the tool's source: field references it
yq '.tools[] | select(.kind == "spanner-execute-sql") | .source' tools.yaml

Type guard

func isSpannerSource(s sources.Source) bool {
    _, ok := s.(spannersql.CompatibleSource)
    return ok
}

Try / catch

tool, err := myTool.ValidateSource(src)
if err != nil {
    log.Fatalf("source binding mismatch: %v (check tools.yaml source: field)", err)
}

Prevention

When it happens

Trigger: Invoking or validating a spanner tool whose YAML config points `source` at a source declared with a kind other than `spanner`; programmatically passing a non-Spanner sources.Source to Tool.Invoke or ValidateSource.

Common situations: Copy-pasting a tools.yaml and forgetting to update the `source:` field; renaming sources so the tool binds to the wrong source; dynamically assembling configs where a generic SQL tool is attached to every source regardless of engine.

Related errors


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