googleapis/mcp-toolbox · critical
tool type %q already registered
Error message
tool type %q already registered
What it means
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.
Source
Thrown at internal/tools/dataplex/dataplexcreatedataproduct/dataplexcreatedataproduct.go:34
import (
"context"
"fmt"
"net/http"
yaml "github.com/goccy/go-yaml"
"github.com/googleapis/mcp-toolbox/internal/sources"
"github.com/googleapis/mcp-toolbox/internal/sources/dataplex"
"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 = "dataplex-create-data-product"
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 {
CreateDataProduct(
ctx context.Context,
locationId string,
dataProductId string,
displayName string,
description string,View on GitHub (pinned to 8cc6e09de2)
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.
Example fix
// before const resourceType string = "dataplex-create-data-product" // conflicts with existing registration // after const resourceType string = "dataplex-create-data-product" // declared once; duplicate removed
Defensive patterns
Strategy: validation
Validate before calling
const want = "dataplex-create-data-product" // verify before building: // git grep -n '"dataplex-create-data-product"' -- '*.go' // a single declaration site is required to avoid the panic.
Try / catch
func init() {
defer func() {
if r := recover(); r != nil {
log.Fatalf("tool %s registration conflict: %v", resourceType, r)
}
}()
tools.Register(resourceType, newConfig)
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: Cloned dataplex tool with unchanged resourceType; merge conflict resolution keeping both registrations; vendored duplicates of the module; test helpers that re-run registration logic.
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/33ae436af4ab875f.
Report an issue: GitHub.