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

ValidateSource for alloydb-list-users checks that the attached source implements compatibleSource (GetDefaultProject, UseClientAuthorization, ListUser). Any other source type is rejected with this error because the tool can only invoke the AlloyDB Admin API through that interface. This is a startup-time wiring guard.

Source

Thrown at internal/tools/alloydb/alloydblistusers/alloydblistusers.go:101

}

// Tool represents the list-users tool.
type Tool struct {
	tools.BaseTool[Config]
}

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
}

// Invoke executes the tool's logic.
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)
	}
	paramsMap := params.AsMap()

	project, ok := paramsMap["project"].(string)
	if !ok || project == "" {
		return nil, util.NewAgentError("invalid or missing 'project' parameter; expected a string", nil)
	}
	location, ok := paramsMap["location"].(string)
	if !ok || location == "" {

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Point the tool's source field at an alloydb source
  2. Verify the source kind is alloydb in tools.yaml
  3. Run config validation locally before deployment

Example fix

// before
source: my-spanner
// after
source: my-alloydb
Defensive patterns

Strategy: validation

Validate before calling

if !strings.HasPrefix(cfg.Source, "alloydb") {
    return fmt.Errorf("tool %s expects an alloydb source, got %q", cfg.Name, cfg.Source)
}

Type guard

func isAlloyDBUserSource(s sources.Source) bool {
    _, ok := s.(interface {
        GetDefaultProject() string
        UseClientAuthorization() bool
        ListUser(context.Context, string, string, string) (any, error)
    })
    return ok
}

Prevention

When it happens

Trigger: ValidateSource called with a non-alloydb source — e.g. tools.yaml binds this tool to a firestore or spanner source.

Common situations: Mistyped source name resolving to the wrong source; template configs for other databases reused for AlloyDB; deleting/renaming the alloydb source but leaving the tool entry.

Related errors


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