{"record":{"id":"291640293fbbbd38","repo":"microsoft/semantic-kernel","slug":"external-message-channel-not-configured-for-step-w","errorCode":null,"errorMessage":"External message channel not configured for step with topic {processEventData.ExternalTopicName}","messagePattern":"External message channel not configured for step with topic (.+?)","errorType":"exception","errorClass":"KernelException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Experimental/Process.Abstractions/KernelProcessStepExternalContext.cs","lineNumber":34,"sourceCode":"    /// </summary>\n    /// <param name=\"externalMessageChannel\">An instance of <see cref=\"IExternalKernelProcessMessageChannel\"/></param>\n    public KernelProcessStepExternalContext(IExternalKernelProcessMessageChannel? externalMessageChannel = null)\n    {\n        this._externalMessageChannel = externalMessageChannel;\n    }\n\n    /// <summary>\n    /// Emit an external event to through a <see cref=\"IExternalKernelProcessMessageChannel\"/>\n    /// component if connected from within the SK process\n    /// </summary>\n    /// <param name=\"processEventData\">data containing event details</param>\n    /// <returns></returns>\n    /// <exception cref=\"KernelException\"></exception>\n    public async Task EmitExternalEventAsync(KernelProcessProxyMessage processEventData)\n    {\n        if (this._externalMessageChannel == null)\n        {\n            throw new KernelException($\"External message channel not configured for step with topic {processEventData.ExternalTopicName}\");\n        }\n\n        await this._externalMessageChannel.EmitExternalEventAsync(processEventData.ExternalTopicName, processEventData).ConfigureAwait(false);\n    }\n\n    /// <summary>\n    /// Closes connection with external messaging channel\n    /// </summary>\n    /// <returns><see cref=\"Task\"/></returns>\n    /// <exception cref=\"KernelException\"></exception>\n    public async Task CloseExternalEventChannelAsync()\n    {\n        if (this._externalMessageChannel == null)\n        {\n            throw new KernelException(\"External message channel not configured for step\");\n        }\n\n        await this._externalMessageChannel.Uninitialize().ConfigureAwait(false);","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/dotnet/src/Experimental/Process.Abstractions/KernelProcessStepExternalContext.cs#L16-L52","documentation":"Thrown by KernelProcessStepExternalContext.EmitExternalEventAsync when no IExternalKernelProcessMessageChannel was injected into the context. The context's _externalMessageChannel field is null because the constructor was called with a null channel argument (the default). The framework cannot route the event to an external bus (e.g., Service Bus, SignalR) without a configured channel.","triggerScenarios":"A KernelProcessStepContext or KernelProcessStepExternalContext is created without passing an IExternalKernelProcessMessageChannel instance, and then EmitExternalEventAsync is called at runtime (typically from within a KernelProcessStep that tries to emit an event externally via the proxy step's external topic).","commonSituations":"Running a process that contains an AddProxyStep but the external message channel was not registered with the kernel or process runtime. Migrating from an older SK version where external channels were optional. Unit-testing a step in isolation without wiring up the external channel infrastructure. Forgetting to call kernelBuilder.WithExternalMessageChannel() (or equivalent setup) before starting the process.","solutions":["Register an IExternalKernelProcessMessageChannel implementation with your process runtime so that KernelProcessStepExternalContext is constructed with a non-null channel.","Verify that the proxy step added via ProcessBuilder.AddProxyStep is accompanied by a matching external channel registration in the kernel/process host configuration.","If the step should not emit externally, remove the call to EmitExternalEventAsync or guard it by checking whether the external context has a configured channel before invoking.","Check that the KernelProcess is started through the process runtime that injects external channels (e.g., KernelProcessFunctionExecution or the process runtime extension), not a bare step activation."],"exampleFix":"// before\nvar context = new KernelProcessStepExternalContext(); // no channel\nawait context.EmitExternalEventAsync(message); // throws\n\n// after\nIExternalKernelProcessMessageChannel channel = new MyMessageChannel();\nvar context = new KernelProcessStepExternalContext(channel);\nawait context.EmitExternalEventAsync(message);","handlingStrategy":"validation","validationCode":"// Before emitting, check if the external context has a channel configured.\n// Note: _externalMessageChannel is private; callers should track whether a channel\n// was provided at construction time.\npublic bool HasExternalChannel(KernelProcessStepExternalContext ctx)\n{\n    // No public API exposes this; you must track it at the process-host level.\n    // Ensure your IExternalKernelProcessMessageChannel is registered before process start.\n    return _externalChannelIsRegistered;\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    await context.EmitExternalEventAsync(message);\n}\ncatch (KernelException ex) when (ex.Message.Contains(\"External message channel not configured\"))\n{\n    _logger.LogWarning(\"External channel not configured; skipping external emit for topic {Topic}\", message.ExternalTopicName);\n}","preventionTips":["Register the IExternalKernelProcessMessageChannel implementation with your process runtime before calling KernelProcess.runAsync.","Verify the channel is non-null in your process host setup code before starting any step that emits externally.","Only add proxy steps (AddProxyStep) when an external channel is available."],"tags":["semantic-kernel","process-framework","external-channel","configuration","messaging"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}