googleapis/mcp-toolbox · critical

tool type %q already registered

Error message

tool type %q already registered

What it means

This panic comes from the package-level init() of the serverlesssparkcreatesparkbatch tool. MCP Toolbox keeps a global registry of tool types keyed by a resource type string; tools.Register returns false if the key already exists, and the package deliberately panics to signal a duplicate registration. It is a programming/registration error, not a runtime failure users can trigger.

Source

Thrown at internal/tools/serverlessspark/serverlesssparkcreatesparkbatch/serverlesssparkcreatesparkbatch.go:32

package serverlesssparkcreatesparkbatch

import (
	"context"
	"fmt"

	dataproc "cloud.google.com/go/dataproc/v2/apiv1/dataprocpb"
	"github.com/goccy/go-yaml"
	"github.com/googleapis/mcp-toolbox/internal/tools"
	"github.com/googleapis/mcp-toolbox/internal/tools/serverlessspark/createbatch"
	"github.com/googleapis/mcp-toolbox/internal/util/parameters"
)

const resourceType = "serverless-spark-create-spark-batch"

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) {
	baseCfg, err := createbatch.NewConfig(ctx, name, decoder)
	if err != nil {
		return nil, err
	}
	return Config{Config: baseCfg}, nil
}

type Config struct {
	createbatch.Config

	ScopesRequired []string `yaml:"scopesRequired"`
}

// validate interface

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Search the codebase for the duplicate resourceType string and change it so each tool registers a unique constant
  2. Check go.mod / vendor/ for a duplicated import path of the same tools package and remove one copy
  3. If a renamed package should replace an old one, remove the old package's init() registration or delete the old package
  4. Rebuild with `go build -o toolbox` and run `go test ./internal/tools/...` to confirm the panic is gone

Example fix

// before
const resourceType = "serverless-spark-create-spark-batch" // duplicate in two packages
// after
const resourceType = "serverless-spark-create-spark-batch-v2" // unique per registering package (or delete the duplicate package)
Defensive patterns

Strategy: validation

Validate before calling

// before importing/registering, ensure uniqueness
grep -rn 'serverless-spark-create-spark-batch' internal/ tools/  # expect exactly one hit
// or in Go: guard tests
tools.Register(resourceType, newConfig) // write a test asserting each resourceType registers exactly once

Prevention

When it happens

Trigger: Two Go packages register the same resourceType string "serverless-spark-create-spark-batch", or the same package is linked twice under different import paths (e.g. vendored copy plus module copy), causing init() to run twice against the same registry.

Common situations: Copy-pasting a tool package and forgetting to change resourceType; accidentally importing a duplicated/forked copy of internal/tools; renaming a package but keeping the old const, colliding with the original that is still imported.

Related errors


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