{"record":{"id":"bffb55980d817bb2","repo":"googleapis/mcp-toolbox","slug":"tool-type-q-already-registered-bffb55","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/dataplexcreatedataasset/dataplexcreatedataasset.go","lineNumber":33,"sourceCode":"package dataplexcreatedataasset\n\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/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-asset\"\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\tCreateDataAsset(\n\t\tctx context.Context,\n\t\tlocationID string,\n\t\tdataProductID string,\n\t\tdataAssetID string,\n\t\tresourceURI string,","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/tools/dataplex/dataplexcreatedataasset/dataplexcreatedataasset.go#L15-L51","documentation":"This panic originates in init() of internal/tools/dataplex/dataplexcreatedataasset because tools.Register(\"dataplex-create-data-asset\", newConfig) returned false, meaning the registry already holds that tool type key. The library fails fast at startup to prevent one tool definition from silently overwriting another. Resolution requires a unique registration per tool type.","triggerScenarios":"Another declaration of the const \"dataplex-create-data-asset\" exists and its init() registers it too; or code (e.g., tests) calls tools.Register again for the same key after package initialization.","commonSituations":"Copy-paste of a sibling dataplex tool without renaming the const; merges bringing duplicate registrations; duplicate module/vendor copies; manual registration in test setup.","solutions":["Search the codebase for \"dataplex-create-data-asset\" and eliminate the duplicate const.","Give each tool package a unique resourceType per naming convention.","Deduplicate linked module copies so init runs once per package path.","Remove manual re-registration calls in tests."],"exampleFix":"// before\nconst resourceType string = \"dataplex-create-data-asset\" // duplicate in another file\n// after\nconst resourceType string = \"dataplex-create-data-asset\" // single source of truth; duplicate deleted","handlingStrategy":"validation","validationCode":"const want = \"dataplex-create-data-asset\"\n// uniqueness check before merge:\n//   git grep -n 'dataplex-create-data-asset' -- '*.go'\n// expect a single const resourceType declaration.","typeGuard":null,"tryCatchPattern":"defer func() {\n    if r := recover(); r != nil {\n        if strings.Contains(fmt.Sprint(r), \"already registered\") {\n            log.Fatalf(\"duplicate dataplex tool type: %v\", r)\n        }\n        panic(r)\n    }\n}()","preventionTips":["Rename resourceType when copying sibling tool packages.","Run a CI grep/uniqueness test over all registered keys.","Restrict tools.Register calls to package init().","Prevent duplicate module copies via go mod tidy and pinned versions.","Boot the server in CI to catch registry panics before release."],"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"}