{"record":{"id":"33ae436af4ab875f","repo":"googleapis/mcp-toolbox","slug":"tool-type-q-already-registered-33ae43","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/dataplex/dataplexcreatedataproduct/dataplexcreatedataproduct.go","lineNumber":34,"sourceCode":"\nimport (\n\t\"context\"\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/dataplex\"\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 = \"dataplex-create-data-product\"\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\tCreateDataProduct(\n\t\tctx context.Context,\n\t\tlocationId string,\n\t\tdataProductId string,\n\t\tdisplayName string,\n\t\tdescription string,","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/tools/dataplex/dataplexcreatedataproduct/dataplexcreatedataproduct.go#L16-L52","documentation":"This panic is thrown by init() in internal/tools/dataplex/dataplexcreatedataproduct when tools.Register for \"dataplex-create-data-product\" finds the key already registered and returns false. The registry intentionally refuses duplicate tool types, and the package panics at startup to make the conflict impossible to miss. Each tool type key must appear exactly once in the binary.","triggerScenarios":"A second init() registers the same \"dataplex-create-data-product\" const (duplicate declaration or double-linked package); or a test/bootstrap path calls tools.Register after init already registered the type.","commonSituations":"Cloned dataplex tool with unchanged resourceType; merge conflict resolution keeping both registrations; vendored duplicates of the module; test helpers that re-run registration logic.","solutions":["Grep for \"dataplex-create-data-product\" and remove/rename the duplicate resourceType declaration.","Maintain one unique resourceType const per tool package.","Verify a single copy of the package is linked (go.mod, vendor).","In tests, rely on init() and avoid re-registering existing types."],"exampleFix":"// before\nconst resourceType string = \"dataplex-create-data-product\" // conflicts with existing registration\n// after\nconst resourceType string = \"dataplex-create-data-product\" // declared once; duplicate removed","handlingStrategy":"validation","validationCode":"const want = \"dataplex-create-data-product\"\n// verify before building:\n//   git grep -n '\"dataplex-create-data-product\"' -- '*.go'\n// a single declaration site is required to avoid the panic.","typeGuard":null,"tryCatchPattern":"func init() {\n    defer func() {\n        if r := recover(); r != nil {\n            log.Fatalf(\"tool %s registration conflict: %v\", resourceType, r)\n        }\n    }()\n    tools.Register(resourceType, newConfig)\n}","preventionTips":["Keep each dataplex tool's resourceType unique and source-prefixed.","Check registry keys with a grep before naming a new tool.","Never re-register a type from tests or custom bootstrap code.","Deduplicate dependencies so init() runs once per package.","Include a startup smoke test in CI."],"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"}