{"record":{"id":"c2873488e267957d","repo":"github/github-mcp-server","slug":"unknown-tools-specified-in-withtools","errorCode":null,"errorMessage":"unknown tools specified in WithTools","messagePattern":"unknown tools specified in WithTools","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/inventory/builder.go","lineNumber":14,"sourceCode":"package inventory\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"maps\"\n\t\"slices\"\n\t\"strings\"\n)\n\nvar (\n\t// ErrUnknownTools is returned when tools specified via WithTools() are not recognized.\n\tErrUnknownTools = errors.New(\"unknown tools specified in WithTools\")\n)\n\n// mcpAppsFeatureFlag is the feature flag name that controls MCP Apps UI metadata.\n// This is defined here to avoid importing pkg/github (which imports pkg/inventory).\n// The value must match github.MCPAppsFeatureFlag.\nconst mcpAppsFeatureFlag = \"remote_mcp_ui_apps\"\n\n// ToolFilter is a function that determines if a tool should be included.\n// Returns true if the tool should be included, false to exclude it.\ntype ToolFilter func(ctx context.Context, tool *ServerTool) (bool, error)\n\n// Builder builds a Registry with the specified configuration.\n// Use NewBuilder to create a builder, chain configuration methods,\n// then call Build() to create the final inventory.\n//\n// Example:\n//\n//\treg := NewBuilder().","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/github/github-mcp-server/blob/0ea1f775a7c73eff1bd2e25904d01136756bbfe2/pkg/inventory/builder.go#L1-L32","documentation":"ErrUnknownTools is returned by inventory.Builder.Build() when one or more tool names passed to WithTools() are neither registered tool names nor deprecated aliases. Build validates every cleaned name against the set of registered tools (plus the deprecated-alias map) and fails hard, listing the offending names in the wrapped message. It signals a configuration mistake: a typo, a removed tool, or a name that only exists in another build/feature set.","triggerScenarios":"Calling WithTools([]string{\"create_issue\"}) when the registered name is 'create_issue' vs 'issue' style renames; a typo like 'get_pull_requests' vs the actual registered name; a tool removed in the current version; a name that is a toolset name rather than a tool name. Build() then returns fmt.Errorf(\"%w: %s\", ErrUnknownTools, names...).","commonSituations":"Upgrading github-mcp-server after tool renames/consolidation and keeping old names in --tools config; mixing up toolset names ('issues', 'repos') with tool names; feature-flag-gated names are NOT a trigger (aliases and flagged tools are pre-resolved); copy-paste from outdated docs.","solutions":["Read the wrapped message: it lists the exact unrecognized names","Check canonical tool names via the repo docs (docs/feature-flags.md, docs/tool-renaming.md) or by listing tools from a working build","Fix typos and replace removed names with their current equivalents (deprecated aliases are auto-resolved, so use the newest name)","If embedding the builder, validate names against your registered ServerTool set before calling WithTools"],"exampleFix":"// before\ninv, err := github.NewInventory(t).WithTools([]string{\"create_issue\", \"add_issue_comment\"}).Build()\n\n// after (names renamed in this version)\ninv, err := github.NewInventory(t).WithTools([]string{\"issue\", \"issue_comment\"}).Build()","handlingStrategy":"validation","validationCode":"// Before WithTools, diff requested names against the registry's tools\nregistry := inventory.NewRegistry() // your populated registry/ServerTool source\nvalid := map[string]bool{}\nfor _, t := range registry.Tools() {\n    valid[t.Tool.Name] = true\n}\nfor _, name := range requestedTools {\n    if !valid[name] {\n        return fmt.Errorf(\"unknown tool %q; check canonical names in docs\", name)\n    }\n}\ninv, err := inventory.NewBuilder().SetTools(registry.Tools()).WithTools(requestedTools).Build()","typeGuard":"// Detect the sentinel in returned errors\nfunc isUnknownTools(err error) bool {\n    return err != nil && errors.Is(err, inventory.ErrUnknownTools)\n}","tryCatchPattern":"inv, err := builder.WithTools(names).Build()\nif err != nil {\n    if errors.Is(err, inventory.ErrUnknownTools) {\n        // config problem: log the listed names and fail fast with a clear message\n        log.Fatalf(\"invalid tools config: %v\", err)\n    }\n    return err // unexpected builder failure\n}","preventionTips":["Treat this sentinel as a config-validation failure: parse the name list from the message and report it","After version upgrades, re-check tool names against docs/tool-renaming.md before regenerating configs","Do not confuse toolset names with tool names; toolsets go to WithToolsets","Add a CI config lint that validates configured tool names against a fresh inventory build"],"tags":["configuration","tool-names","builder","validation","inventory"],"backgroundTag":null,"analyzedSha":"0ea1f775a7c73eff1bd2e25904d01136756bbfe2","analyzedAt":"2026-08-15T18:10:19.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}