{"record":{"id":"62c8263f22a9f74e","repo":"microsoft/semantic-kernel","slug":"failed-to-create-process-thread","errorCode":null,"errorMessage":"Failed to create process thread.","messagePattern":"Failed to create process thread\\.","errorType":"exception","errorClass":"KernelException","httpStatus":null,"severity":"critical","filePath":"dotnet/src/Experimental/Process.LocalRuntime/LocalProcess.cs","lineNumber":241,"sourceCode":"                {\n                    ThreadId = thread.Id,\n                    ThreadName = kvp.Key,\n                    ThreadType = threadDefinition.ThreadType,\n                    ThreadPolicy = threadDefinition.ThreadPolicy\n                };\n            }\n            else\n            {\n                var thread = new KernelProcessAgentThread\n                {\n                    ThreadId = null,\n                    ThreadName = kvp.Key,\n                    ThreadType = threadDefinition.ThreadType,\n                    ThreadPolicy = threadDefinition.ThreadPolicy\n                };\n            }\n\n            this._threads.Add(kvp.Key, processThread ?? throw new KernelException(\"Failed to create process thread.\"));\n        }\n\n        // Initialize the steps within this process\n        foreach (var step in this._stepsInfos)\n        {\n            LocalStep? localStep = null;\n\n            // The current step should already have a name.\n            Verify.NotNull(step.State?.Name);\n\n            if (step is KernelProcess processStep)\n            {\n                // The process will only have an Id if its already been executed.\n                if (string.IsNullOrWhiteSpace(processStep.State.Id))\n                {\n                    processStep = processStep with { State = processStep.State with { Id = Guid.NewGuid().ToString() } };\n                }\n","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/dotnet/src/Experimental/Process.LocalRuntime/LocalProcess.cs#L223-L259","documentation":"Thrown during LocalProcess.InitializeProcessAsync when processThread is null after the thread initialization loop. For Scoped threads the thread is created via CreateAgentThreadAsync; for non-Scoped threads the code creates a local variable 'thread' but never assigns it to processThread, so the null-coalescing throw always fires for non-Scoped thread policies. This is a code defect in the else branch at line 232.","triggerScenarios":"Defining any process thread with ThreadPolicy other than KernelProcessThreadLifetime.Scoped (e.g., Transient or Singleton). The else branch constructs a KernelProcessAgentThread but stores it in a throwaway local variable instead of processThread, guaranteeing the exception on the next line.","commonSituations":"Using agent steps with non-Scoped thread policies; upgrading the process framework to a version that introduced the KernelProcessThreadLifetime enum; any process that declares threads in its Threads dictionary.","solutions":["If you control the framework source: fix line 232-238 to assign to processThread instead of a local variable (change 'var thread =' to 'processThread =').","If using a published package: upgrade to a version where this bug is fixed, or file an issue against the Semantic Kernel repository.","As a workaround until fixed: declare all process threads with KernelProcessThreadLifetime.Scoped so the if-branch executes and processThread is correctly assigned.","If no threads are needed, ensure the process's Threads dictionary is empty."],"exampleFix":"// before (framework bug in LocalProcess.cs)\nelse\n{\n    var thread = new KernelProcessAgentThread { ... };\n}\nthis._threads.Add(kvp.Key, processThread ?? throw ...);\n// after\nelse\n{\n    processThread = new KernelProcessAgentThread { ... };\n}\nthis._threads.Add(kvp.Key, processThread ?? throw ...);","handlingStrategy":"validation","validationCode":"// Workaround: only use Scoped thread lifetime until the framework bug is fixed\nforeach (var kvp in process.Threads)\n{\n    if (kvp.Value.ThreadPolicy != KernelProcessThreadLifetime.Scoped)\n    {\n        // This will trigger the bug in current LocalProcess.cs; force Scoped or skip the thread\n        kvp.Value.ThreadPolicy = KernelProcessThreadLifetime.Scoped;\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["If consuming the NuGet package, check release notes for a fix before using non-Scoped thread policies.","If building from source, patch line 232 to assign 'processThread' instead of 'var thread'.","File an issue in the Semantic Kernel repo with the reproduction (any non-Scoped thread definition)."],"tags":["process-framework","threads","agents","bug","initialization"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}