{"record":{"id":"ef8487b8fe08ba91","repo":"microsoft/semantic-kernel","slug":"proxy-step-does-not-have-linked-steps-to-it-link","errorCode":null,"errorMessage":"Proxy step does not have linked steps to it, link step edges to proxy or remove proxy step","messagePattern":"Proxy step does not have linked steps to it, link step edges to proxy or remove proxy step","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Experimental/Process.Core/ProcessProxyBuilder.cs","lineNumber":72,"sourceCode":"        {\n            throw new InvalidOperationException($\"Topic name {topicName} is not registered as proxy publish event, register first before using\");\n        }\n\n        if (usedTopic)\n        {\n            throw new InvalidOperationException($\"Topic name {topicName} is is already linked to another step edge\");\n        }\n\n        this._eventMetadata[eventData.EventName] = new() { EventId = eventData.EventId, TopicName = topicName };\n        this._externalTopicUsage[topicName] = true;\n    }\n\n    /// <inheritdoc/>\n    internal override KernelProcessStepInfo BuildStep(ProcessBuilder processBuilder, KernelProcessStepStateMetadata? stateMetadata = null)\n    {\n        if (this._externalTopicUsage.All(topic => !topic.Value))\n        {\n            throw new InvalidOperationException(\"Proxy step does not have linked steps to it, link step edges to proxy or remove proxy step\");\n        }\n\n        KernelProcessProxyStateMetadata proxyMetadata = new()\n        {\n            Name = this.Name,\n            Id = this.Id,\n            EventMetadata = this._eventMetadata,\n            PublishTopics = this._externalTopicUsage.ToList().Select(topic => topic.Key).ToList(),\n        };\n\n        // Build the edges first\n        var builtEdges = this.Edges.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Select(e => e.Build()).ToList());\n\n        KernelProcessStepState state = new(this.Name, this.Version, this.Id);\n\n        return new KernelProcessProxy(state, builtEdges)\n        {\n            ProxyMetadata = proxyMetadata","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/dotnet/src/Experimental/Process.Core/ProcessProxyBuilder.cs#L54-L90","documentation":"Thrown by ProcessProxyBuilder.BuildStep when none of the registered external topics have been linked to a step edge (all entries in _externalTopicUsage are false). A proxy step with no linked edges serves no purpose and indicates a configuration error — the proxy was added but never wired to any publishing step.","triggerScenarios":"Calling BuildStep (directly or via ProcessBuilder.Build) on a proxy step where LinkTopicToStepEdgeInfo was never called for any topic, or where all link calls were skipped.","commonSituations":"Adding a proxy step but forgetting to wire step edges to it; building the process before completing the edge graph; conditional code that skips edge linking under certain configurations; early prototype code with a placeholder proxy.","solutions":["Call LinkTopicToStepEdgeInfo for at least one topic before building the process.","If the proxy is not needed, remove the AddProxyStep call instead of leaving an unlinked proxy.","Review the process construction logic to ensure all proxy steps are fully wired before Build."],"exampleFix":"// before\nvar proxy = process.AddProxyStep(\"myProxy\", externalTopics: new[] { \"topicA\" });\n// forgot to link any step edge to topicA\nvar kernelProcess = process.Build(); // throws in BuildStep\n\n// after — link a step edge before building\nproxy.LinkTopicToStepEdgeInfo(\"topicA\", sourceStep, eventData);\nvar kernelProcess = process.Build();","handlingStrategy":"validation","validationCode":"// Before building, verify each proxy has at least one linked edge\n// (requires tracking link calls; if not possible, catch at Build time)\nif (!hasLinkedAnyEdge)\n    throw new InvalidOperationException(\"Proxy step has no linked edges. Link a step edge or remove the proxy.\");\n\nvar kernelProcess = process.Build();","typeGuard":null,"tryCatchPattern":"try\n{\n    var kernelProcess = process.Build();\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"does not have linked steps\"))\n{\n    logger.LogError(\"Proxy step not wired: {Message}\", ex.Message);\n    // Remove the proxy or add the missing edge links, then rebuild\n}","preventionTips":["Always call LinkTopicToStepEdgeInfo for at least one topic before Build.","If a proxy is not needed, remove it rather than leaving it unlinked.","Add a pre-build validation pass that checks all proxy steps have at least one linked edge."],"tags":["proxy-step","build-validation","edge-linking","dotnet"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}