{"record":{"id":"103eb76a1ed146aa","repo":"googleapis/mcp-toolbox","slug":"unknown-tool-type","errorCode":null,"errorMessage":"unknown tool type","messagePattern":"unknown tool type","errorType":"error_code","errorClass":"ErrUnknownToolType","httpStatus":null,"severity":"error","filePath":"internal/tools/tools.go","lineNumber":52,"sourceCode":"type ToolConfigFactory func(ctx context.Context, name string, decoder *yaml.Decoder) (ToolConfig, error)\n\nvar toolRegistry = make(map[string]ToolConfigFactory)\n\n// Register allows individual tool packages to register their configuration\n// factory function. This is typically called from an init() function in the\n// tool's package. It associates a 'type' string with a function that can\n// produce the specific ToolConfig type. It returns true if the registration was\n// successful, and false if a tool with the same type was already registered.\nfunc Register(resourceType string, factory ToolConfigFactory) bool {\n\tif _, exists := toolRegistry[resourceType]; exists {\n\t\t// Tool with this type already exists, do not overwrite.\n\t\treturn false\n\t}\n\ttoolRegistry[resourceType] = factory\n\treturn true\n}\n\nvar ErrUnknownToolType = fmt.Errorf(\"unknown tool type\")\n\n// DecodeConfig looks up the registered factory for the given type and uses it\n// to decode the tool configuration.\nfunc DecodeConfig(ctx context.Context, resourceType string, name string, decoder *yaml.Decoder) (ToolConfig, error) {\n\tfactory, found := toolRegistry[resourceType]\n\tif !found {\n\t\treturn nil, fmt.Errorf(\"%w: %q\", ErrUnknownToolType, resourceType)\n\t}\n\ttoolConfig, err := factory(ctx, name, decoder)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to parse tool %q as type %q: %w\", name, resourceType, err)\n\t}\n\treturn toolConfig, nil\n}\n\ntype ToolConfig interface {\n\tToolConfigType() string\n\tInitialize(context.Context) (Tool, error)","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/tools/tools.go#L34-L70","documentation":"ErrUnknownToolType is the sentinel error returned by DecodeConfig when the `tool` (resourceType) found in the config has no entry in the toolRegistry — i.e., no tool package registered that kind (registration happens via init() in each tool package). Callers like the server use errors.Is to detect it and may skip unknown tools when configured to.","triggerScenarios":"YAML tool config with a `kind:` that is misspelled, unsupported, or from a newer toolbox version than the binary; building a custom binary without importing the package that registers the desired tool (blank import), so the registry lacks the type.","commonSituations":"Typo in kind (e.g. `sqlite-executesql` vs `sqlite-execute-sql`); using a prebuilt config from docs with an older toolbox binary; trimming tool imports in a custom build and losing registry entries.","solutions":["Fix the tool's `kind:` in the YAML to a registered type exactly as documented (kebab-case).","Upgrade the toolbox binary to a version that supports the tool kind.","If building custom binaries, ensure the tool packages are imported (blank imports) so init() registers them.","If intentional, enable ignore-unknown-tools so unknown tool kinds are skipped with a warning."],"exampleFix":"# before\ntools:\n  q:\n    kind: sqlite-execute-sqlx   # typo, unregistered\n    source: my-sqlite\n# after\ntools:\n  q:\n    kind: sqlite-execute-sql\n    source: my-sqlite\n    description: \"Run SQL.\"","handlingStrategy":"try-catch","validationCode":"# check kind is recognized by your binary:\ntoolbox --tools-file tools.yaml --prebuilt my-config 2>&1 | grep -i 'unknown tool type'\n# or verify against the docs list of supported tool kinds for your version","typeGuard":"var knownKinds = map[string]bool{\"sqlite-execute-sql\": true, \"spanner-execute-sql\": true /* ... */}\nfunc kindRegistered(kind string) bool { return knownKinds[kind] }","tryCatchPattern":"toolCfg, err := tools.DecodeConfig(ctx, resourceType, name, dec)\nif err != nil {\n    if errors.Is(err, tools.ErrUnknownToolType) {\n        log.Warnf(\"skipping unknown tool kind %q\", resourceType)\n        return nil // or fail fast, per your policy\n    }\n    return err\n}","preventionTips":["Copy tool `kind:` values exactly from the docs for your toolbox version.","Keep the toolbox binary version in sync with any prebuilt configs you use.","When building custom binaries, blank-import every tool package so init() registers it.","Run the config through the server once in a CI job to catch unregistered kinds early."],"tags":["go","config","registry","yaml","unknown-type"],"backgroundTag":"unknown-tool-type","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"}