{"record":{"id":"b9534aefca5f509b","repo":"microsoft/semantic-kernel","slug":"the-proxy-step-can-only-handle-1-parameter-object","errorCode":null,"errorMessage":"The proxy step can only handle 1 parameter object","messagePattern":"The proxy step can only handle 1 parameter object","errorType":"exception","errorClass":"KernelException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Experimental/Process.LocalRuntime/LocalProxy.cs","lineNumber":42,"sourceCode":"    /// <param name=\"proxy\">an instance of <see cref=\"KernelProcessProxy\"/></param>\n    /// <param name=\"kernel\">An instance of <see cref=\"Kernel\"/></param>\n    internal LocalProxy(KernelProcessProxy proxy, Kernel kernel)\n        : base(proxy, kernel)\n    {\n        this._proxy = proxy;\n        this._logger = this._kernel.LoggerFactory?.CreateLogger(this._proxy.State.Name) ?? new NullLogger<LocalStep>();\n    }\n\n    internal override void AssignStepFunctionParameterValues(ProcessMessage message)\n    {\n        if (this._functions is null || this._inputs is null || this._initialInputs is null)\n        {\n            throw new KernelException(\"The step has not been initialized.\").Log(this._logger);\n        }\n\n        if (message.Values.Count != 1)\n        {\n            throw new KernelException(\"The proxy step can only handle 1 parameter object\").Log(this._logger);\n        }\n\n        var kvp = message.Values.Single();\n\n        if (this._inputs.TryGetValue(message.FunctionName, out Dictionary<string, object?>? functionName) && functionName != null && functionName.TryGetValue(kvp.Key, out object? parameterName) && parameterName != null)\n        {\n            this._logger.LogWarning(\"Step {StepName} already has input for {FunctionName}.{Key}, it is being overwritten with a message from Step named '{SourceId}'.\", this.Name, message.FunctionName, kvp.Key, message.SourceId);\n        }\n\n        if (!this._inputs.TryGetValue(message.FunctionName, out Dictionary<string, object?>? functionParameters))\n        {\n            this._inputs[message.FunctionName] = [];\n            functionParameters = this._inputs[message.FunctionName];\n        }\n\n        if (this._proxy.ProxyMetadata != null && message.SourceEventId != null && this._proxy.ProxyMetadata.EventMetadata.TryGetValue(message.SourceEventId, out var metadata) && metadata != null)\n        {\n            functionParameters![kvp.Key] = KernelProcessProxyMessageFactory.CreateProxyMessage(this.ParentProcessId!, message.SourceEventId, metadata.TopicName, kvp.Value);","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/dotnet/src/Experimental/Process.LocalRuntime/LocalProxy.cs#L24-L60","documentation":"Thrown by LocalProxy.AssignStepFunctionParameterValues when message.Values contains more or fewer than exactly one entry. A proxy step wraps a single external operation and can only accept one parameter object per message; it does not aggregate multiple input parameters like a regular step does.","triggerScenarios":"A ProcessMessage routed to a LocalProxy step contains a Values dictionary with a count other than 1. This happens when an edge targeting the proxy step maps multiple parameters, or when the message factory produces a multi-value message for a proxy target.","commonSituations":"Configuring an edge to a proxy step with multiple parameter mappings; sending a regular multi-parameter ProcessMessage to a proxy step; misunderstanding that proxy steps accept only a single opaque parameter object.","solutions":["Ensure edges targeting a KernelProcessProxy step deliver exactly one value in the message.","If multiple values are needed, wrap them in a single composite object before sending.","Review the edge's OutputTarget (KernelProcessFunctionTarget) parameter mapping to confirm only one parameter is targeted."],"exampleFix":"// before - proxy step receives multiple parameters\nmsg.Values = new Dictionary<string, object?> { [\"a\"] = val1, [\"b\"] = val2 };\n// after - wrap into a single parameter object\nmsg.Values = new Dictionary<string, object?> { [\"input\"] = new { A = val1, B = val2 } };","handlingStrategy":"validation","validationCode":"// Validate that edges targeting proxy steps deliver exactly one parameter\nforeach (var edgeList in process.Edges.Values)\n{\n    foreach (var edge in edgeList)\n    {\n        if (edge.OutputTarget is KernelProcessFunctionTarget ft && proxyStepIds.Contains(ft.StepId))\n        {\n            // Ensure the function target maps only one parameter\n            if (ft.ParameterNames is null || ft.ParameterNames.Count != 1) { /* warn or fix */ }\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Design proxy step edges to carry exactly one parameter value.","Wrap multiple values into a single composite object before sending to a proxy step.","Document that proxy steps accept only one parameter to guide edge configuration."],"tags":["process-framework","proxy-step","message-routing","configuration"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}