{"record":{"id":"5d17a88323aa6547","repo":"github/copilot-sdk","slug":"tool-tool-name-received-non-object-arguments","errorCode":null,"errorMessage":"Tool '{tool.Name}' received non-object arguments, but its schema does not define exactly one parameter or one required parameter.","messagePattern":"Tool '(.+?)' received non-object arguments, but its schema does not define exactly one parameter or one required parameter\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Session.cs","lineNumber":1084,"sourceCode":"                    {\n                        if (requiredParameterName is not null)\n                        {\n                            requiredParameterName = null;\n                            break;\n                        }\n\n                        requiredParameterName = requiredParameter.GetString();\n                    }\n\n                    if (requiredParameterName is not null &&\n                        properties.TryGetProperty(requiredParameterName, out _))\n                    {\n                        return requiredParameterName;\n                    }\n                }\n            }\n\n            throw new ArgumentException(\n                $\"Tool '{tool.Name}' received non-object arguments, but its schema does not define exactly one parameter or one required parameter.\");\n        }\n    }\n\n    private bool TryClaimExternalTool(string requestId, CancellationTokenSource cancellationSource)\n        => ((ICollection<KeyValuePair<string, CancellationTokenSource>>)_pendingExternalTools)\n            .Remove(new(requestId, cancellationSource));\n\n    private void CancelExternalTool(string requestId)\n    {\n        if (!string.IsNullOrEmpty(requestId) && _pendingExternalTools.TryRemove(requestId, out var cancellationSource))\n        {\n            _ = Task.Run(() =>\n            {\n                try\n                {\n                    cancellationSource.Cancel();\n                }","sourceCodeStart":1066,"sourceCodeEnd":1102,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/dotnet/src/Session.cs#L1066-L1102","documentation":"When a tool is called with non-object (e.g. string, array) arguments, the SDK must map that single value to exactly one tool parameter. If the tool's input schema does not define exactly one parameter — or exactly one required parameter — the SDK cannot decide where the value goes and throws ArgumentException.","triggerScenarios":"Calling a tool whose inputSchema has 0 or 2+ parameters (or multiple required ones) while passing arguments that are not a JSON object, e.g. `CallTool(\"search\", \"my query\")` instead of an object.","commonSituations":"LLMs emitting bare strings as tool arguments; wrapping a positional-style tool call against an MCP tool with multiple properties; hand-written clients using JSON-RPC positional params for tools with multi-property schemas.","solutions":["Pass tool arguments as a JSON object keyed by the schema's property names.","If bare values must be supported, make the tool schema define exactly one parameter (or exactly one required parameter).","Instruct/constrain the model to emit object-form arguments matching the tool's inputSchema.","Catch ArgumentException around tool dispatch and return a descriptive invalid-params error to the caller."],"exampleFix":"// before\nawait session.CallToolAsync(\"search\", JsonSerializer.SerializeToElement(\"cats\"));\n\n// after\nawait session.CallToolAsync(\"search\", JsonSerializer.SerializeToElement(new { query = \"cats\" }));","handlingStrategy":"validation","validationCode":"if (args.ValueKind != JsonValueKind.Object &&\n    (tool.Schema.Properties?.Count != 1 || tool.Schema.Required?.Count != 1))\n    throw new ArgumentException($\"Tool '{tool.Name}' requires object arguments\");","typeGuard":"static bool ArgsFitTool(JsonElement args, Tool tool) =>\n    args.ValueKind == JsonValueKind.Object ||\n    (tool.Schema?.Properties?.Count == 1 && (tool.Schema.Required?.Count ?? 0) <= 1);","tryCatchPattern":"try { await session.CallToolAsync(name, args); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"non-object arguments\"))\n{ return ToolError.InvalidParams(name, ex.Message); }","preventionTips":["Always pass tool arguments as a JSON object keyed by schema properties","Design single-parameter schemas if positional/bare args must be supported","Constrain the model to emit object-form tool arguments"],"tags":["tool-invocation","schema","arguments","dotnet"],"backgroundTag":"invalid-argument-value","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"}