{"record":{"id":"605cce922196540a","repo":"github/copilot-sdk","slug":"invalid-field-entry-there-is-no-bare-wildca","errorCode":null,"errorMessage":"Invalid {field} entry '*': there is no bare wildcard. Use `new ToolSet().AddBuiltIn(\"*\")`, `.AddMcp(\"*\")`, or `.AddCustom(\"*\")` to target a specific source.","messagePattern":"Invalid (.+?) entry '\\*': there is no bare wildcard\\. Use `new ToolSet\\(\\)\\.AddBuiltIn\\(\"\\*\"\\)`, `\\.AddMcp\\(\"\\*\"\\)`, or `\\.AddCustom\\(\"\\*\"\\)` to target a specific source\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Client.cs","lineNumber":950,"sourceCode":"    }\n\n    /// <summary>\n    /// Catches misuse of <see cref=\"SessionConfigBase.AvailableTools\"/> /\n    /// <see cref=\"SessionConfigBase.ExcludedTools\"/> at the SDK boundary so\n    /// callers get an actionable error rather than a silently-empty filter.\n    /// The runtime treats a bare <c>\"*\"</c> as a literal name match for a tool\n    /// whose name is the single character <c>*</c>, which the runtime's\n    /// charset guard would reject at registration — so the filter effectively\n    /// matches nothing.\n    /// </summary>\n    private static void ValidateToolFilterList(string field, IList<string>? list)\n    {\n        if (list is null) return;\n        foreach (var entry in list)\n        {\n            if (entry == \"*\")\n            {\n                throw new ArgumentException(\n                    $\"Invalid {field} entry '*': there is no bare wildcard. \" +\n                    \"Use `new ToolSet().AddBuiltIn(\\\"*\\\")`, `.AddMcp(\\\"*\\\")`, or \" +\n                    \"`.AddCustom(\\\"*\\\")` to target a specific source.\",\n                    nameof(list));\n            }\n        }\n    }\n\n    /// <summary>\n    /// Resolves <see cref=\"SessionConfigBase.AvailableTools\"/> /\n    /// <see cref=\"SessionConfigBase.ExcludedTools\"/> for the wire payload,\n    /// validating empty-mode requirements. <c>toolFilterPrecedence</c> is\n    /// always <c>excluded</c> so SDK consumers get composable allowlist /\n    /// denylist semantics.\n    /// </summary>\n    private (IList<string>? AvailableTools, IList<string>? ExcludedTools, OptionsUpdateToolFilterPrecedence ToolFilterPrecedence) ResolveToolFilterOptions(SessionConfigBase config)\n    {\n        ValidateToolFilterList(nameof(SessionConfigBase.AvailableTools), config.AvailableTools);","sourceCodeStart":932,"sourceCodeEnd":968,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/dotnet/src/Client.cs#L932-L968","documentation":"The CopilotClient constructor throws this ArgumentException when a tool filter list (AvailableTools/ExcludedTools) contains the bare wildcard entry '*'. There is no bare-wildcard semantics; you must target a specific tool source (built-in, MCP, or custom) using the ToolSet builder methods.","triggerScenarios":"Passing a session config whose AvailableTools or ExcludedTools list (e.g. a List<string> or ToolSet string entries) contains the literal \"*\"; ValidateToolFilterList iterates every entry and throws on the first bare \"*\".","commonSituations":"Assuming '*' means 'all tools' as it does in some other SDKs; hand-writing config files with \"tools\": [\"*\"]; migrating from an API where a bare wildcard was allowed.","solutions":["Replace \"*\" with new ToolSet().AddBuiltIn(\"*\"), .AddMcp(\"*\"), or .AddCustom(\"*\") depending on which source you want.","Omit AvailableTools entirely if you want the default tool selection.","Enumerate the specific tools you need instead of using a wildcard."],"exampleFix":"// before\nvar config = new SessionConfig { AvailableTools = new List<string> { \"*\" } };\n// after\nvar config = new SessionConfig { AvailableTools = new ToolSet().AddBuiltIn(\"*\").AddMcp(\"*\").AddCustom(\"*\") };","handlingStrategy":"validation","validationCode":"if (availableTools?.Contains(\"*\") == true || excludedTools?.Contains(\"*\") == true)\n    throw new ArgumentException(\"Use AddBuiltIn/AddMcp/AddCustom instead of a bare '*' entry.\");","typeGuard":"static bool HasBareWildcard(IEnumerable<string>? list) => list?.Any(e => e == \"*\") == true;","tryCatchPattern":"try { client = new CopilotClient(options, connection); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"bare wildcard\")) { /* fix the tool list in config before retrying */ }","preventionTips":["Never hand-write \"*\" into tool lists; always use the ToolSet builder","Validate tool config files at load time","Share a single ToolSet factory to avoid divergent list construction"],"tags":["dotnet","configuration","tools","wildcard","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}