{"record":{"id":"384fd33f6a027adb","repo":"microsoft/semantic-kernel","slug":"the-derived-deactivateasync-method-failed-to-compl","errorCode":null,"errorMessage":"The derived DeactivateAsync method failed to complete for step {this.Name}.","messagePattern":"The derived DeactivateAsync method failed to complete for step (.+?)\\.","errorType":"exception","errorClass":"KernelException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Experimental/Process.LocalRuntime/LocalProxy.cs","lineNumber":101,"sourceCode":"    /// <summary>\n    /// Deinitialization of the Proxy Step, calling <see cref=\"KernelProxyStep.DeactivateAsync(KernelProcessStepExternalContext)\"/>\n    /// </summary>\n    /// <returns></returns>\n    public override async Task DeinitializeStepAsync()\n    {\n        MethodInfo? derivedMethod = this._stepInfo.InnerStepType.GetMethod(\n            nameof(KernelProxyStep.DeactivateAsync),\n            BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,\n            binder: null,\n            types: [typeof(KernelProcessStepExternalContext)],\n            modifiers: null);\n\n        if (derivedMethod != null && this._stepInstance != null)\n        {\n            var context = new KernelProcessStepExternalContext(this.ExternalMessageChannel);\n            ValueTask deactivateTask =\n                (ValueTask?)derivedMethod.Invoke(this._stepInstance, [context]) ??\n                throw new KernelException($\"The derived DeactivateAsync method failed to complete for step {this.Name}.\").Log(this._logger);\n\n            await deactivateTask.ConfigureAwait(false);\n        }\n    }\n}\n","sourceCodeStart":83,"sourceCodeEnd":107,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/dotnet/src/Experimental/Process.LocalRuntime/LocalProxy.cs#L83-L107","documentation":"Thrown by LocalProxy.DeinitializeStepAsync when the reflection-invoked DeactivateAsync method on the proxy step's inner type returns null instead of a ValueTask. The code uses methodInfo.Invoke to call the derived DeactivateAsync(KernelProcessStepExternalContext) and expects a non-null ValueTask result. A null return means the method's return type is not ValueTask or the invocation produced no result.","triggerScenarios":"The inner step type (KernelProcessProxyStep subclass) declares a DeactivateAsync method matching the expected signature but its return type is not ValueTask (e.g., returns Task or void), causing the cast to ValueTask? to yield null.","commonSituations":"Implementing a custom KernelProxyStep with a DeactivateAsync override that returns Task instead of ValueTask; signature mismatch (wrong parameter types); framework version changes to the expected return type.","solutions":["Ensure the custom KernelProxyStep subclass's DeactivateAsync method returns ValueTask and accepts a KernelProcessStepExternalContext parameter.","Match the exact method signature: 'protected internal virtual ValueTask DeactivateAsync(KernelProcessStepExternalContext context)'.","If no custom deactivation logic is needed, remove the override so the base implementation is used."],"exampleFix":"// before - returns Task instead of ValueTask\npublic override Task DeactivateAsync(KernelProcessStepExternalContext context) { ... }\n// after - returns ValueTask\npublic override ValueTask DeactivateAsync(KernelProcessStepExternalContext context) { ... }","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// Verify the step type's DeactivateAsync returns ValueTask before registering\nvar method = typeof(TProxyStep).GetMethod(nameof(KernelProxyStep.DeactivateAsync),\n    BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,\n    binder: null, types: [typeof(KernelProcessStepExternalContext)], modifiers: null);\nif (method?.ReturnType != typeof(ValueTask))\n{\n    throw new InvalidOperationException($\"{typeof(TProxyStep).Name}.DeactivateAsync must return ValueTask.\");\n}","tryCatchPattern":null,"preventionTips":["Always match the KernelProxyStep.DeactivateAsync signature: ValueTask return type with KernelProcessStepExternalContext parameter.","Add a unit test that reflects on your proxy step types to verify method signatures.","Avoid changing the return type when overriding virtual methods."],"tags":["process-framework","proxy-step","reflection","deactivation","api-contract"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}