github/copilot-sdk · error · ArgumentException
Invalid entry '*': there is no bare wildcard. Use `new…
Error message
Invalid {field} entry '*': there is no bare wildcard. Use `new ToolSet().AddBuiltIn("*")`, `.AddMcp("*")`, or `.AddCustom("*")` to target a specific source. What it means
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.
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.
Example fix
// before
var config = new SessionConfig { AvailableTools = new List<string> { "*" } };
// after
var config = new SessionConfig { AvailableTools = new ToolSet().AddBuiltIn("*").AddMcp("*").AddCustom("*") }; Defensive patterns
Strategy: validation
Validate before calling
if (availableTools?.Contains("*") == true || excludedTools?.Contains("*") == true)
throw new ArgumentException("Use AddBuiltIn/AddMcp/AddCustom instead of a bare '*' entry."); Type guard
static bool HasBareWildcard(IEnumerable<string>? list) => list?.Any(e => e == "*") == true;
Try / catch
try { client = new CopilotClient(options, connection); }
catch (ArgumentException ex) when (ex.Message.Contains("bare wildcard")) { /* fix the tool list in config before retrying */ } Prevention
- 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
When it happens
Trigger: 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 "*".
Common situations: 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.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- CopilotClient is in Mode = CopilotClientMode.Empty but the…
- Unsupported RuntimeConnection type
- invalid entry '*': there is no bare wildcard. Use…
- Client is in Mode=ModeEmpty but the session config did not…
- sessionFs.initialCwd is required
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/605cce922196540a.
Report an issue: GitHub.
Appendix: source
Thrown at dotnet/src/Client.cs:950
}
/// <summary>
/// Catches misuse of <see cref="SessionConfigBase.AvailableTools"/> /
/// <see cref="SessionConfigBase.ExcludedTools"/> at the SDK boundary so
/// callers get an actionable error rather than a silently-empty filter.
/// The runtime treats a bare <c>"*"</c> as a literal name match for a tool
/// whose name is the single character <c>*</c>, which the runtime's
/// charset guard would reject at registration — so the filter effectively
/// matches nothing.
/// </summary>
private static void ValidateToolFilterList(string field, IList<string>? list)
{
if (list is null) return;
foreach (var entry in list)
{
if (entry == "*")
{
throw new ArgumentException(
$"Invalid {field} entry '*': there is no bare wildcard. " +
"Use `new ToolSet().AddBuiltIn(\"*\")`, `.AddMcp(\"*\")`, or " +
"`.AddCustom(\"*\")` to target a specific source.",
nameof(list));
}
}
}
/// <summary>
/// Resolves <see cref="SessionConfigBase.AvailableTools"/> /
/// <see cref="SessionConfigBase.ExcludedTools"/> for the wire payload,
/// validating empty-mode requirements. <c>toolFilterPrecedence</c> is
/// always <c>excluded</c> so SDK consumers get composable allowlist /
/// denylist semantics.
/// </summary>
private (IList<string>? AvailableTools, IList<string>? ExcludedTools, OptionsUpdateToolFilterPrecedence ToolFilterPrecedence) ResolveToolFilterOptions(SessionConfigBase config)
{
ValidateToolFilterList(nameof(SessionConfigBase.AvailableTools), config.AvailableTools);View on GitHub (pinned to cd8cf15dc3)