{"record":{"id":"43ea1827be338910","repo":"github/copilot-sdk","slug":"no-toolinvocation-was-provided-for-the-tool-call","errorCode":null,"errorMessage":"No ToolInvocation was provided for the tool call.","messagePattern":"No ToolInvocation was provided for the tool call\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"dotnet/src/CopilotTool.cs","lineNumber":86,"sourceCode":"                    return new AIFunctionFactoryOptions.ParameterBindingOptions\n                    {\n                        ExcludeFromSchema = true,\n                        BindParameter = static (pi, arguments) =>\n                        {\n                            // CopilotClient/CopilotSession attach this context object before invoking the AIFunction.\n                            if (arguments.Context is not null &&\n                                arguments.Context.TryGetValue(typeof(ToolInvocation), out var invocation) &&\n                                invocation is ToolInvocation toolInvocation)\n                            {\n                                return toolInvocation;\n                            }\n\n                            if (pi.HasDefaultValue)\n                            {\n                                return null;\n                            }\n\n                            throw new InvalidOperationException($\"No {nameof(ToolInvocation)} was provided for the tool call.\");\n                        }\n                    };\n                }\n\n                return bindingOptions;\n            };\n        }\n\n        static void ApplyToolOptions(AIFunctionFactoryOptions factoryOptions, CopilotToolOptions? toolOptions)\n        {\n            if (toolOptions is not null && (toolOptions.OverridesBuiltInTool || toolOptions.SkipPermission || toolOptions.IsTerminal || toolOptions.Defer is not null || toolOptions.Metadata is not null))\n            {\n                Dictionary<string, object?> additionalProperties = new(StringComparer.Ordinal);\n                if (factoryOptions.AdditionalProperties is not null)\n                {\n                    foreach (var (key, value) in factoryOptions.AdditionalProperties)\n                    {\n                        additionalProperties[key] = value;","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/dotnet/src/CopilotTool.cs#L68-L104","documentation":"When defining a tool, the library builds a parameter binder that extracts the ToolInvocation for each argument. If a required (non-defaulted) parameter receives no ToolInvocation at invocation time, this InvalidOperationException is thrown because the tool cannot be executed without it.","triggerScenarios":"Invoking a tool whose invocation context omitted the ToolInvocation for a required parameter — e.g. the caller passed null/absent invocation data, or the tool was invoked outside the normal Copilot tool-call flow.","commonSituations":"Manually invoking the bound delegate without supplying an invocation; a runtime sends a malformed tool call missing arguments; parameter lists changed (new required parameter added) while callers still use the old signature.","solutions":["Ensure every tool call passes a ToolInvocation and all required (non-optional) parameter values","Give the parameter a default value if it is genuinely optional","Update callers when the tool signature gains new required parameters","Validate the incoming tool-call payload before binding"],"exampleFix":"// before\n// required parameter 'invocation' has no default; caller omitted it\nvar result = await tool.InvokeAsync(args);\n// after\npublic async Task<object?> InvokeAsync(ToolInvocation invocation, Dictionary<string, object?> args)\n{\n    if (invocation is null) throw new ArgumentNullException(nameof(invocation));\n    return await tool.InvokeAsync(invocation, args);\n}","handlingStrategy":"validation","validationCode":"if (invocation is null) throw new ArgumentNullException(nameof(invocation), \"ToolInvocation is required for the tool call\");","typeGuard":"bool InvocationProvided(ToolInvocation? invocation) => invocation is not null;","tryCatchPattern":"try { var result = await tool.InvokeAsync(invocation, args); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"ToolInvocation\")) { /* reject the malformed tool call */ }","preventionTips":["Always pass a ToolInvocation when invoking tools","Give genuinely optional parameters default values","Validate tool-call payloads before binding"],"tags":["tools","binding","argument","dotnet"],"backgroundTag":"missing-required-argument","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}