googleapis/mcp-toolbox · critical
tool type %q already registered
Error message
tool type %q already registered
What it means
This panic comes from init() in internal/tools/datalineage/datalineagesearchlineage: tools.Register("datalineage-search-lineage", newConfig) returned false because the key already exists in the registry. The registry treats duplicate tool types as a programming error and the package panics immediately at startup. Each tool type key must be unique across the whole binary.
Source
Thrown at internal/tools/datalineage/datalineagesearchlineage/datalineagesearchlineage.go:35
import (
"context"
"fmt"
"net/http"
"strings"
lineagepb "cloud.google.com/go/datacatalog/lineage/apiv1/lineagepb"
"github.com/goccy/go-yaml"
"github.com/googleapis/mcp-toolbox/internal/sources"
"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 = "datalineage-search-lineage"
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 {
SearchLineageStreaming(
ctx context.Context,
parentLocation string,
locations []string,
rootEntities []*lineagepb.EntityReference,
direction lineagepb.SearchLineageStreamingRequest_SearchDirection,View on GitHub (pinned to 8cc6e09de2)
Solutions
- Search the codebase for "datalineage-search-lineage" and delete or rename the duplicate const.
- Ensure a single unique resourceType per tool package.
- Deduplicate go.mod/vendor entries that could link the package twice.
- Do not manually re-register init-registered tools in tests.
Example fix
// before const resourceType string = "datalineage-search-lineage" // also declared in another package // after const resourceType string = "datalineage-search-lineage" // single declaration; duplicate removed
Defensive patterns
Strategy: validation
Validate before calling
const want = "datalineage-search-lineage" // pre-change validation: // git grep -n 'datalineage-search-lineage' -- '*.go' // one const declaration + one init() use = safe; anything more panics.
Try / catch
defer func() {
if r := recover(); r != nil {
log.Fatalf("datalineage registration conflict: %v", r)
}
}() Prevention
- Assign a fresh, unique resourceType to every new tool package.
- Detect duplicates in CI with a registry-key uniqueness test.
- Confine registration to init(); skip manual re-registration in test scaffolding.
- Avoid multiple module copies that would double-run init().
- Review merge results for accidental duplicate tool definitions.
When it happens
Trigger: A second declaration of the const "datalineage-search-lineage" elsewhere in the build registers the same key; or registration code is invoked a second time (tests, custom bootstrap) after package init.
Common situations: Copy-paste of the datalineage tool package without changing the const; merge conflicts reintroducing a duplicate; vendor/module duplication causing double init; test helpers re-running registration.
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/513819c191001d2d.
Report an issue: GitHub.