github/copilot-sdk · error · ArgumentException
Invalid tool name: must not be null or empty.
Error message
Invalid {kind} tool name: must not be null or empty. What it means
ToolSet.ValidateName rejects tool names that are null or the empty string when adding tools of any kind (built-in, custom, MCP). Every tool in the set must have a usable identifier; the wildcard "*" is checked next and allowed, but empty is never valid.
Solutions
- Provide a non-empty name string to AddBuiltIn/AddCustom/AddMcp.
- Filter or skip tool definitions with null/empty names before adding them.
- Guard in your own loading code with string.IsNullOrEmpty and log/skip the offending entry.
- Catch ArgumentException (paramName == "name") around batch tool registration to identify the bad entry.
Example fix
// before toolSet.AddCustom(config.Name); // config.Name == "" // after if (!string.IsNullOrEmpty(config.Name)) toolSet.AddCustom(config.Name);
Defensive patterns
Strategy: validation
Validate before calling
if (string.IsNullOrEmpty(name))
throw new ArgumentException("Tool name must not be null or empty", nameof(name)); Type guard
static bool IsValidToolNameBase(string? name) => !string.IsNullOrEmpty(name);
Try / catch
try { toolSet.AddCustom(name); }
catch (ArgumentException ex) when (ex.ParamName == "name" && ex.Message.Contains("must not be null or empty"))
{ logger.LogError("Skipping tool with blank name"); } Prevention
- Skip tool definitions with null/empty names when loading from config or MCP
- Validate metadata at deserialization time
- Log skipped entries so missing names surface early
When it happens
Trigger: Calling ToolSet.AddBuiltIn(null), AddCustom(""), or AddMcp with an empty name — typically when a tool entry was constructed from data where the name field is missing or empty.
Common situations: MCP servers or config files listing tools without a name; deserialized tool metadata with null Name; string.Split/parse producing empty entries passed to Add*.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- The value cannot be an empty string or composed entirely of…
- GitHubToken and GitHubTokenProvider cannot be used together.
- SetModelOptions.AutoTier and SetModelOptions.ResetAutoTier…
- Invalid tool name ' ': tool names must match…
- Expected a non-empty string token when reading
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/c0fc70c8e5b31e84.
Report an issue: GitHub.
Appendix: source
Thrown at dotnet/src/ToolSet.cs:104
/// Adds an MCP tool pattern. Matches tools advertised by any configured
/// MCP server.
/// </summary>
/// <param name="toolName">The runtime's canonical wire name for the MCP
/// tool (e.g. <c>"github-list_issues"</c>), or <c>"*"</c> to match all
/// MCP tools from any server.</param>
/// <returns>This <see cref="ToolSet"/> for chaining.</returns>
public ToolSet AddMcp(string toolName)
{
ValidateName("mcp", toolName);
Add($"mcp:{toolName}");
return this;
}
private static void ValidateName(string kind, string name)
{
if (string.IsNullOrEmpty(name))
{
throw new ArgumentException(
$"Invalid {kind} tool name: must not be null or empty.",
nameof(name));
}
if (name == "*")
{
return;
}
if (!s_validToolName.IsMatch(name))
{
throw new ArgumentException(
$"Invalid {kind} tool name '{name}': tool names must match /^[a-zA-Z0-9_-]+$/ " +
"or be the wildcard '*'.",
nameof(name));
}
}
}
/// <summary>View on GitHub (pinned to cd8cf15dc3)