{"record":{"id":"5c055d6db93f814f","repo":"googleapis/mcp-toolbox","slug":"tool-type-q-already-registered-5c055d","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/dataplexcheckdataquality/dataplexcheckdataquality.go","lineNumber":34,"sourceCode":"\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"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/tools/dataplex/dataplexcommon\"\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-check-data-quality\"\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\tProjectID() string\n\tGenerateDataQuality(ctx context.Context, location, resourcePath string, specJSON string, publish bool) (string, error)\n}\n\ntype Config struct {\n\ttools.ConfigBase `yaml:\",inline\"`","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/tools/dataplex/dataplexcheckdataquality/dataplexcheckdataquality.go#L16-L52","documentation":"This panic is raised by init() in internal/tools/dataplex/dataplexcheckdataquality when tools.Register finds \"dataplex-check-data-quality\" already in the registry and returns false. The library panics at startup to guarantee one tool type maps to exactly one Config factory. The key must be unique for the process to boot.","triggerScenarios":"Duplicate resourceType const declared in another file/package whose init() also registers \"dataplex-check-data-quality\"; or explicit re-registration from test/bootstrap code after init.","commonSituations":"Copy-pasted dataplex tool with unchanged const; merge introducing two identical tool types; vendoring duplicate module copies; tests calling Register after package init already ran.","solutions":["Grep the repo for \"dataplex-check-data-quality\" and remove or rename the duplicate resourceType.","Enforce unique kebab-case resourceType per tool package.","Check for duplicate module copies (go.mod/vendor) causing double init.","Restructure tests so they do not re-register init-registered tools."],"exampleFix":"// before\nconst resourceType string = \"dataplex-check-data-quality\" // registered twice\n// after\nconst resourceType string = \"dataplex-check-data-quality\" // keep single declaration; delete duplicate","handlingStrategy":"validation","validationCode":"const want = \"dataplex-check-data-quality\"\n// before building, verify uniqueness:\n//   git grep -n '\"dataplex-check-data-quality\"' -- '*.go'\n// more than one const hit guarantees a startup panic.","typeGuard":null,"tryCatchPattern":"func init() {\n    defer func() {\n        if r := recover(); r != nil {\n            log.Fatalf(\"dataplex tool registration failed: %v\", r)\n        }\n    }()\n    tools.Register(resourceType, newConfig)\n}","preventionTips":["One resourceType const per tool package, no exceptions.","Grep the key before adding any new dataplex tool.","Register only via init().","Keep go.mod deduplicated to avoid double package init.","Add a smoke test that boots the registry and would surface duplicate 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"}