googleapis/mcp-toolbox · critical
tool type %q already registered
Error message
tool type %q already registered
What it means
This panic originates in init() of internal/tools/databaseinsights/getindexrecommendations: tools.Register(resourceType, newConfig) returned false because "databaseinsights-get-index-recommendations" was already registered in the global tool map. The library panics during program startup so a duplicate tool definition can never silently replace an existing one. Fixing it requires making the tool type key unique across the binary.
Source
Thrown at internal/tools/databaseinsights/getindexrecommendations/getindexrecommendations.go:35
import (
"context"
"encoding/json"
"fmt"
"net/http"
yaml "github.com/goccy/go-yaml"
"github.com/googleapis/mcp-toolbox/internal/sources"
"github.com/googleapis/mcp-toolbox/internal/sources/databaseinsights"
"github.com/googleapis/mcp-toolbox/internal/tools"
"github.com/googleapis/mcp-toolbox/internal/util"
"github.com/googleapis/mcp-toolbox/internal/util/parameters"
)
const resourceType string = "databaseinsights-get-index-recommendations"
func init() {
if !tools.Register(resourceType, newConfig) {
panic(fmt.Sprintf("tool type %q already registered", resourceType))
}
}
func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (tools.ToolConfig, error) {
actual := Config{ConfigBase: tools.ConfigBase{Name: name}}
if err := decoder.DecodeContext(ctx, &actual); err != nil {
return nil, err
}
return actual, nil
}
type compatibleSource interface {
BatchQueryIndexRecommendations(ctx context.Context, req *databaseinsights.BatchQueryIndexRecommendationsRequest) (*databaseinsights.BatchQueryIndexRecommendationsResponse, error)
}
type Config struct {
tools.ConfigBase `yaml:",inline"`
Type string `yaml:"type" validate:"required"`View on GitHub (pinned to 8cc6e09de2)
Solutions
- Search the repository for "databaseinsights-get-index-recommendations" and eliminate the duplicate declaration.
- Assign a unique resourceType to each tool package per naming conventions.
- Deduplicate module/vendor copies so the package is linked only once.
- Remove manual tools.Register calls in tests that duplicate init-time registration.
Example fix
// before const resourceType string = "databaseinsights-get-index-recommendations" // registered twice // after const resourceType string = "databaseinsights-index-recommendations" // or delete the duplicate package copy
Defensive patterns
Strategy: validation
Validate before calling
const want = "databaseinsights-get-index-recommendations" // pre-merge check: // git grep -n 'databaseinsights-get-index-recommendations' -- '*.go' // Expect exactly one declaration site plus its init() usage.
Try / catch
defer func() {
if r := recover(); r != nil {
if s, ok := r.(string); ok && strings.Contains(s, "already registered") {
log.Fatalf("duplicate tool type: %s", s)
}
panic(r)
}
}() Prevention
- Rename the resourceType whenever you fork or copy a tool package.
- Verify with a repo-wide grep that the chosen key is unique before merging.
- Register exclusively in init(); never re-register in tests.
- Keep dependencies deduplicated so the package links once.
- Add CI startup checks that fail the build on registry panics.
When it happens
Trigger: A duplicate resourceType constant exists elsewhere in the build and both init() functions call tools.Register; or custom/bootstrap code re-registers the same tool type after package initialization.
Common situations: Copy-pasted tool package with unchanged const; merge bringing two identical registrations; test scaffolding that re-runs registration; accidental duplicate import of the same package under two module versions.
Related errors
- tool type %q already registered
- tool type %q already registered
- tool type %q already registered
- tool type %q already registered
- tool type %q already registered
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/624b76c737dfe1eb.
Report an issue: GitHub.