microsoft/semantic-kernel · critical · KernelException

Failed to create process thread.

Error message

Failed to create process thread.

What it means

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.

Source

Thrown at dotnet/src/Experimental/Process.LocalRuntime/LocalProcess.cs:241

                {
                    ThreadId = thread.Id,
                    ThreadName = kvp.Key,
                    ThreadType = threadDefinition.ThreadType,
                    ThreadPolicy = threadDefinition.ThreadPolicy
                };
            }
            else
            {
                var thread = new KernelProcessAgentThread
                {
                    ThreadId = null,
                    ThreadName = kvp.Key,
                    ThreadType = threadDefinition.ThreadType,
                    ThreadPolicy = threadDefinition.ThreadPolicy
                };
            }

            this._threads.Add(kvp.Key, processThread ?? throw new KernelException("Failed to create process thread."));
        }

        // Initialize the steps within this process
        foreach (var step in this._stepsInfos)
        {
            LocalStep? localStep = null;

            // The current step should already have a name.
            Verify.NotNull(step.State?.Name);

            if (step is KernelProcess processStep)
            {
                // The process will only have an Id if its already been executed.
                if (string.IsNullOrWhiteSpace(processStep.State.Id))
                {
                    processStep = processStep with { State = processStep.State with { Id = Guid.NewGuid().ToString() } };
                }

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. If you control the framework source: fix line 232-238 to assign to processThread instead of a local variable (change 'var thread =' to 'processThread =').
  2. If using a published package: upgrade to a version where this bug is fixed, or file an issue against the Semantic Kernel repository.
  3. As a workaround until fixed: declare all process threads with KernelProcessThreadLifetime.Scoped so the if-branch executes and processThread is correctly assigned.
  4. If no threads are needed, ensure the process's Threads dictionary is empty.

Example fix

// before (framework bug in LocalProcess.cs)
else
{
    var thread = new KernelProcessAgentThread { ... };
}
this._threads.Add(kvp.Key, processThread ?? throw ...);
// after
else
{
    processThread = new KernelProcessAgentThread { ... };
}
this._threads.Add(kvp.Key, processThread ?? throw ...);
Defensive patterns

Strategy: validation

Validate before calling

// Workaround: only use Scoped thread lifetime until the framework bug is fixed
foreach (var kvp in process.Threads)
{
    if (kvp.Value.ThreadPolicy != KernelProcessThreadLifetime.Scoped)
    {
        // This will trigger the bug in current LocalProcess.cs; force Scoped or skip the thread
        kvp.Value.ThreadPolicy = KernelProcessThreadLifetime.Scoped;
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/62c8263f22a9f74e. Report an issue: GitHub.