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

  1. Search the codebase for "datalineage-search-lineage" and delete or rename the duplicate const.
  2. Ensure a single unique resourceType per tool package.
  3. Deduplicate go.mod/vendor entries that could link the package twice.
  4. 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

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


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/513819c191001d2d. Report an issue: GitHub.