{"record":{"id":"1cadc4ab00b244da","repo":"microsoft/aspire","slug":"toolbox-name-must-contain-at-least-one-tool","errorCode":null,"errorMessage":"Toolbox '{name}' must contain at least one tool.","messagePattern":"Toolbox '(.+?)' must contain at least one tool\\.","errorType":"validation","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Foundry/Toolbox/FoundryToolboxReconciler.cs","lineNumber":64,"sourceCode":"\n    public IReadOnlyDictionary<string, string> Metadata { get; }\n\n    public string ConfigurationHash { get; }\n\n    public static FoundryToolboxDeploymentDefinition Create(\n        string name,\n        string description,\n        IReadOnlyList<ResolvedFoundryToolboxTool> tools,\n        IReadOnlyDictionary<string, string> metadata)\n    {\n        ArgumentException.ThrowIfNullOrEmpty(name);\n        ArgumentException.ThrowIfNullOrWhiteSpace(description);\n        ArgumentNullException.ThrowIfNull(tools);\n        ArgumentNullException.ThrowIfNull(metadata);\n\n        if (tools.Count == 0)\n        {\n            throw new InvalidOperationException($\"Toolbox '{name}' must contain at least one tool.\");\n        }\n\n        var duplicateToolNames = tools\n            .GroupBy(tool => tool.Name, StringComparer.Ordinal)\n            .Where(group => group.Count() > 1)\n            .Select(group => group.Key)\n            .Order(StringComparer.Ordinal)\n            .ToArray();\n\n        if (duplicateToolNames.Length > 0)\n        {\n            throw new InvalidOperationException(\n                $\"Toolbox '{name}' contains duplicate tool names: {string.Join(\", \", duplicateToolNames)}.\");\n        }\n\n        var duplicateMcpServerLabels = tools\n            .Where(tool => tool.McpServerLabel is not null)\n            .GroupBy(tool => tool.McpServerLabel!, StringComparer.Ordinal)","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Foundry/Toolbox/FoundryToolboxReconciler.cs#L46-L82","documentation":"Thrown by FoundryToolboxReconciler.Create when the tools collection is empty (after null checks). A Toolbox must declare at least one tool definition; creating one with zero tools would produce a useless remote Toolbox, so it is rejected eagerly as an invalid operation.","triggerScenarios":"Calling Create (via AddFoundryToolbox-style builders) with an empty tools list — e.g. conditionally-added tools were all skipped, or the caller forgot to add any With*Tool calls.","commonSituations":"Building the tool list from configuration where all entries were filtered out; refactoring that removed tool registrations; feature flags disabling every tool at runtime.","solutions":["Add at least one tool definition (WithMcpTool, AddAiSearchTool, or a Bing grounding tool) before creating the Toolbox.","If tools come from configuration, validate the list is non-empty before calling Create and surface a clear startup error.","If conditional tool registration is intentional, guard the Toolbox creation itself behind the same condition."],"exampleFix":"// before\nvar tools = config.EnabledTools.Select(...).ToArray(); // empty when nothing enabled\nvar toolbox = FoundryToolboxReconciler.Create(\"tb\", desc, tools, metadata);\n// after\nif (tools.Count == 0) throw new InvalidOperationException(\"No tools enabled in configuration; cannot create Toolbox.\");\nvar toolbox = FoundryToolboxReconciler.Create(\"tb\", desc, tools, metadata);","handlingStrategy":"validation","validationCode":"if (tools is not { Count: > 0 })\n{\n    throw new InvalidOperationException(\"At least one tool must be registered before creating a Foundry Toolbox.\");\n}","typeGuard":"static bool HasTools(IReadOnlyList<FoundryToolDefinition> tools) => tools.Count > 0;","tryCatchPattern":"try\n{\n    var toolbox = FoundryToolboxReconciler.Create(name, description, tools, metadata);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"must contain at least one tool\"))\n{\n    logger.LogError(ex, \"Toolbox {Name} was created with no tools.\", name);\n    throw;\n}","preventionTips":["Assert tool registrations in app-model unit tests so an empty toolbox fails at test time.","Fail fast at config load when conditional tool registration yields an empty list.","Pair every conditional tool-removal with a guard on Toolbox creation."],"tags":["validation","empty-collection","foundry-toolbox"],"backgroundTag":"empty-required-field","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}