{"record":{"id":"a967bc3b99855e89","repo":"microsoft/aspire","slug":"a-global-mcp-approval-policy-cannot-be-combined-with-custom","errorCode":null,"errorMessage":"A global MCP approval policy cannot be combined with custom filters.","messagePattern":"A global MCP approval policy cannot be combined with custom filters\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Foundry/Toolbox/FoundryToolboxToolDefinition.cs","lineNumber":227,"sourceCode":"{\n    public static ResolvedFoundryToolboxMcpApprovalPolicy? Create(\n        FoundryToolboxMcpApprovalPolicy? policy)\n    {\n        if (policy is null)\n        {\n            return null;\n        }\n\n        var always = ResolvedFoundryToolboxMcpApprovalFilter.Create(\n            policy.Always,\n            nameof(policy.Always));\n        var never = ResolvedFoundryToolboxMcpApprovalFilter.Create(\n            policy.Never,\n            nameof(policy.Never));\n\n        if (policy.Global is not null && (always is not null || never is not null))\n        {\n            throw new ArgumentException(\n                \"A global MCP approval policy cannot be combined with custom filters.\",\n                nameof(policy));\n        }\n\n        if (policy.Global is null && always is null && never is null)\n        {\n            throw new ArgumentException(\n                \"An MCP approval policy must specify a global mode or at least one custom filter.\",\n                nameof(policy));\n        }\n\n        if (policy.Global is not null &&\n            policy.Global is not FoundryToolboxMcpGlobalApprovalMode.Never &&\n            policy.Global is not FoundryToolboxMcpGlobalApprovalMode.Always)\n        {\n            throw new ArgumentOutOfRangeException(\n                nameof(policy),\n                policy.Global,","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Foundry/Toolbox/FoundryToolboxToolDefinition.cs#L209-L245","documentation":"FoundryToolboxMcpApprovalPolicy.Create enforces the OpenAI MCP require_approval wire contract: a global approval mode (a plain string) and custom always/never filter objects are mutually exclusive. Providing Global together with Always or Never filters makes the resulting wire JSON ambiguous, so an ArgumentException naming the 'policy' parameter is thrown at tool-definition construction time.","triggerScenarios":"Constructing a FoundryToolboxMcpApprovalPolicy with Global set to Never or Always AND also supplying an Always or Never FoundryToolboxMcpApprovalFilter in the same policy.","commonSituations":"Copy-pasting sample code that sets Global then adding tool-specific filters for other tools in the same policy; trying to express 'always require approval except these tools' with a single policy instead of two policies.","solutions":["Remove the Global mode and keep only the always/never filters.","Remove the always/never filters and keep only Global.","Split the intent across multiple MCP tool definitions with separate policies.","Validate the policy before constructing the tool definition."],"exampleFix":"// before\nnew FoundryToolboxMcpApprovalPolicy { Global = Never, Always = filter }\n// after\nnew FoundryToolboxMcpApprovalPolicy { Always = filter } // or Global only","handlingStrategy":"validation","validationCode":"bool valid = policy.Global is null || (policy.Always is null && policy.Never is null);\nif (!valid) throw new ArgumentException(\"Global mode cannot be combined with custom filters.\");","typeGuard":"static bool IsExclusive(FoundryToolboxMcpApprovalPolicy p) =>\n    p.Global is null ? true : (p.Always is null && p.Never is null);","tryCatchPattern":"try { toolDefinition = CreateMcpTool(...); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"cannot be combined with custom filters\"))\n{ logger.LogError(\"Approval policy sets both Global and filters; keep one.\"); }","preventionTips":["Decide between a global mode or per-tool filters when designing the policy","Never merge sample configs that mix Global and filters","Add a unit test asserting policy exclusivity before tool creation"],"tags":["foundry","mcp","approval-policy","invalid-configuration","aspire"],"backgroundTag":"mutually-exclusive-options","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"}