googleapis/mcp-toolbox · critical
tool type %q already registered
Error message
tool type %q already registered
What it means
This panic is raised by init() in internal/tools/databaseinsights/getadvancedtimeserieswaiteventstats because tools.Register was called with the resourceType "databaseinsights-get-advanced-time-series-wait-event-stats", which the registry already contains. tools.Register returns false on duplicate keys and the package panics to fail fast. It protects the invariant that each tool type maps to exactly one Config factory.
Source
Thrown at internal/tools/databaseinsights/getadvancedtimeserieswaiteventstats/getadvancedtimeserieswaiteventstats.go:34
import (
"context"
"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-advanced-time-series-wait-event-stats"
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 {
FetchWaitEventTimeSeries(ctx context.Context, req *databaseinsights.FetchWaitEventTimeSeriesRequest) (*databaseinsights.FetchWaitEventTimeSeriesResponse, error)
}
type Config struct {
tools.ConfigBase `yaml:",inline"`
Type string `yaml:"type" validate:"required"`View on GitHub (pinned to 8cc6e09de2)
Solutions
- Grep for "databaseinsights-get-advanced-time-series-wait-event-stats" and remove/rename the duplicate resourceType.
- Ensure the const is unique per tool package (kebab-case, source-prefixed).
- Check go.mod/vendor for duplicate copies of the module that would double-link the package.
- In test code, avoid re-registering types already registered by init().
Example fix
// before const resourceType string = "databaseinsights-get-advanced-time-series-wait-event-stats" // conflicts with existing key // after const resourceType string = "databaseinsights-get-advanced-wait-event-timeseries" // renamed unique key
Defensive patterns
Strategy: validation
Validate before calling
const want = "databaseinsights-get-advanced-time-series-wait-event-stats" // Run before adding the tool: // git grep -n 'databaseinsights-get-advanced-time-series-wait-event-stats' -- '*.go' // More than one `const resourceType` hit means the registration will panic.
Try / catch
func safeRegister() (recovered any) {
defer func() { recovered = recover() }()
tools.Register(resourceType, newConfig)
return nil
}
// at startup: if r := safeRegister(); r != nil { log.Fatalf("registry conflict: %v", r) } Prevention
- Keep one canonical resourceType declaration per tool package.
- Search the registry keys before choosing a new tool type name.
- Do not manually invoke registration helpers that init() already runs.
- Pin module versions to prevent duplicate package copies.
- Enforce uniqueness with a unit test that asserts every registered key appears once.
When it happens
Trigger: Two init() paths register the same resourceType constant (duplicate declaration in another package/file), or a test utility invokes the registration function a second time after package initialization.
Common situations: Cloning a neighboring databaseinsights tool and forgetting to update the const; rebasing/merging that reintroduced an identical tool type; vendor or module duplication linking the package twice under different import paths.
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/9e0292abcc207168.
Report an issue: GitHub.