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
Tool.ValidateSource in elasticsearchesql.go checks that the source attached to the tool implements the tool's private `compatibleSource` interface (i.e. it is an Elasticsearch source, not some other database source). If the Go type assertion `source.(compatibleSource)` fails, the toolbox cannot run ES|QL against that source and refuses to register/serve the tool. This is a configuration-time type mismatch between the tool and its bound source.
Source
Thrown at internal/tools/elasticsearch/elasticsearchesql/elasticsearchesql.go:102
tools.GetAnnotationsOrDefault(c.Annotations, tools.NewReadOnlyAnnotations),
tools.Manifest{Description: c.Description, Parameters: c.Parameters.Manifest(), AuthRequired: c.AuthRequired},
c.Parameters,
),
}, 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
}
func (t Tool) Invoke(ctx context.Context, s sources.Source, params parameters.ParamValues, accessToken tools.AccessToken) (any, util.ToolboxError) {
source, ok := s.(compatibleSource)
if !ok {
return nil, util.NewClientServerError("source used is not compatible with the tool", http.StatusInternalServerError, nil)
}
var cancel context.CancelFunc
if t.Cfg.Timeout > 0 {
ctx, cancel = context.WithTimeout(ctx, time.Duration(t.Cfg.Timeout)*time.Second)
defer cancel()
} else {
ctx, cancel = context.WithTimeout(ctx, time.Minute)
defer cancel()
}
View on GitHub (pinned to 8cc6e09de2)
Solutions
- Point the tool's `source` field at a source of kind `elasticsearch` in tools.yaml
- Check the source's `kind` value under `sources:` matches what this tool requires (elasticsearch)
- If you meant a different database, use that engine's SQL tool type instead of elasticsearch-esql
- Re-run toolbox and verify with `toolbox --tools-file` / the tools endpoint that the tool loads
Example fix
// before (tools.yaml)
tools:
run-esql:
kind: elasticsearch-esql
source: my-postgres-source
// after
tools:
run-esql:
kind: elasticsearch-esql
source: my-elasticsearch-source Defensive patterns
Strategy: validation
Validate before calling
// Before serving/using the tool, verify the bound source kind in tools.yaml:
// yamlPath: tools.<name>.source -> sources.<srcName>.kind == "elasticsearch"
func sourceKindIs(cfg map[string]any, toolName, want string) bool {
tools := cfg["tools"].(map[string]any)
t := tools[toolName].(map[string]any)
srcName := t["source"].(string)
src := cfg["sources"].(map[string]any)[srcName].(map[string]any)
return src["kind"] == want
}
// sourceKindIs(cfg, "run-esql", "elasticsearch") Type guard
// Mirrors the library check: assert the source implements the compatible interface.
if esSrc, ok := src.(elasticsearchesql.CompatibleSource); ok {
_ = esSrc // safe to use with the esql tool
} else {
return fmt.Errorf("source %T is not an Elasticsearch source", src)
} Try / catch
if err := tool.ValidateSource(src); err != nil {
log.Fatalf("tool %s misconfigured: %v", toolName, err)
} Prevention
- Keep one source per engine with an unambiguous name (e.g. `elasticsearch-prod`)
- After editing tools.yaml, run the toolbox once locally to catch validation errors before deploy
- Lint tools.yaml in CI: assert each tool's source kind matches the tool family
- Never reuse a source name across engines in multi-source configs
When it happens
Trigger: Declaring a tool of kind `elasticsearch-esql` whose `source` field references a source defined with a different SourceConfigType (e.g. a Postgres, AlloyDB or CloudSQL source) so that ValidateSource receives a sources.Source that does not satisfy compatibleSource.
Common situations: Copy-pasting a tools.yaml between configs and pointing esql tools at a non-Elasticsearch source; renaming a source but leaving the tool's `source:` key bound to an old unrelated source; composing prebuilt configs where the source kind was changed to a different database.
Related errors
- invalid source for %q tool: source %q is not a compatible ty
- invalid source for %q tool: source %q is not a compatible ty
- invalid source for %q tool: source %q is not a compatible ty
- invalid source for %q tool: source %q is not a compatible ty
- invalid source for %q tool: source %q is not a compatible ty
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/754c5d68e0f38926.
Report an issue: GitHub.