{"record":{"id":"624b76c737dfe1eb","repo":"googleapis/mcp-toolbox","slug":"tool-type-q-already-registered-624b76","errorCode":null,"errorMessage":"tool type %q already registered","messagePattern":"tool type %q already registered","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"internal/tools/databaseinsights/getindexrecommendations/getindexrecommendations.go","lineNumber":35,"sourceCode":"import (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\n\tyaml \"github.com/goccy/go-yaml\"\n\t\"github.com/googleapis/mcp-toolbox/internal/sources\"\n\t\"github.com/googleapis/mcp-toolbox/internal/sources/databaseinsights\"\n\t\"github.com/googleapis/mcp-toolbox/internal/tools\"\n\t\"github.com/googleapis/mcp-toolbox/internal/util\"\n\t\"github.com/googleapis/mcp-toolbox/internal/util/parameters\"\n)\n\nconst resourceType string = \"databaseinsights-get-index-recommendations\"\n\nfunc init() {\n\tif !tools.Register(resourceType, newConfig) {\n\t\tpanic(fmt.Sprintf(\"tool type %q already registered\", resourceType))\n\t}\n}\n\nfunc newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (tools.ToolConfig, error) {\n\tactual := Config{ConfigBase: tools.ConfigBase{Name: name}}\n\tif err := decoder.DecodeContext(ctx, &actual); err != nil {\n\t\treturn nil, err\n\t}\n\treturn actual, nil\n}\n\ntype compatibleSource interface {\n\tBatchQueryIndexRecommendations(ctx context.Context, req *databaseinsights.BatchQueryIndexRecommendationsRequest) (*databaseinsights.BatchQueryIndexRecommendationsResponse, error)\n}\n\ntype Config struct {\n\ttools.ConfigBase `yaml:\",inline\"`\n\tType             string                 `yaml:\"type\" validate:\"required\"`","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/tools/databaseinsights/getindexrecommendations/getindexrecommendations.go#L17-L53","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nconst resourceType string = \"databaseinsights-get-index-recommendations\" // registered twice\n// after\nconst resourceType string = \"databaseinsights-index-recommendations\" // or delete the duplicate package copy","handlingStrategy":"validation","validationCode":"const want = \"databaseinsights-get-index-recommendations\"\n// pre-merge check:\n//   git grep -n 'databaseinsights-get-index-recommendations' -- '*.go'\n// Expect exactly one declaration site plus its init() usage.","typeGuard":null,"tryCatchPattern":"defer func() {\n    if r := recover(); r != nil {\n        if s, ok := r.(string); ok && strings.Contains(s, \"already registered\") {\n            log.Fatalf(\"duplicate tool type: %s\", s)\n        }\n        panic(r)\n    }\n}()","preventionTips":["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."],"tags":["go","panic","init","tool-registry","duplicate-registration"],"backgroundTag":"duplicate-tool-type-registration","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}