googleapis/mcp-toolbox · critical
tool type %q already registered
Error message
tool type %q already registered
What it means
This panic is thrown by the package-level init() of internal/tools/databaseinsights/getadvancedaggregatedwaiteventstats when tools.Register(resourceType, newConfig) returns false. Register returns false only if the tool type key "databaseinsights-get-advanced-aggregated-wait-event-stats" already exists in the global registry, meaning two registrations raced or the same package/type was registered twice. It is a deliberate fail-fast to prevent silent tool overwrites.
Source
Thrown at internal/tools/databaseinsights/getadvancedaggregatedwaiteventstats/getadvancedaggregatedwaiteventstats.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-advanced-aggregated-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 {
FetchWaitEventStats(ctx context.Context, req *databaseinsights.FetchWaitEventStatsRequest) (*databaseinsights.FetchWaitEventStatsResponse, error)
}
type Config struct {
tools.ConfigBase `yaml:",inline"`
Type string `yaml:"type" validate:"required"`View on GitHub (pinned to 8cc6e09de2)
Solutions
- Grep the repo for "databaseinsights-get-advanced-aggregated-wait-event-stats" and remove or rename the duplicate resourceType declaration.
- Ensure each tool package has a unique resourceType const (follow kebab-case <source>-<tool> convention).
- Run `go list -deps ./... | sort | uniq -d` / tidy go.mod so the package is only linked once.
- If a test re-triggers init, restructure so registration happens once per process (package init is idempotent per binary; duplicates come from duplicated consts).
Example fix
// before const resourceType string = "databaseinsights-get-advanced-aggregated-wait-event-stats" // duplicated in another file // after const resourceType string = "databaseinsights-get-advanced-aggregated-wait-event-stats-v2" // or remove the duplicate declaration
Defensive patterns
Strategy: validation
Validate before calling
const want = "databaseinsights-get-advanced-aggregated-wait-event-stats"
if n := strings.Count(runtime_AllDecls(), want); n > 1 {
panic(fmt.Sprintf("resourceType %s declared %d times", want, n))
} Try / catch
// Go panics cannot be caught in normal code; recover only at a boundary:
func safeInit() {
defer func() {
if r := recover(); r != nil {
log.Fatalf("tool registration failed: %v", r)
}
}()
registerTool(resourceType, newConfig)
} Prevention
- Declare each resourceType const in exactly one file per tool package.
- Grep the resourceType string before adding a new tool to confirm it is unused.
- Follow the <source>-<tool> kebab-case naming convention so keys never collide.
- Keep tool registration solely in package init(); never call Register again from tests or bootstrap.
- Run `go build ./...` and startup smoke tests in CI to catch duplicate-registry panics early.
When it happens
Trigger: Calling tools.Register twice with the same resourceType (duplicate const value across files/packages, a package linked twice via conflicting module versions, or a test/helper that re-runs registration code).
Common situations: Copy-pasting a tool package and forgetting to change the resourceType const; merging branches that both introduce the same tool type; import cycles or vendoring that pull two copies of the package into the build; test harnesses that initialize the registry more than once.
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/e2e565f51c22f02c.
Report an issue: GitHub.