{"record":{"id":"c5b9291eaf8e8ffa","repo":"microsoft/semantic-kernel","slug":"agent-failure-run-terminated-run-status-run-c5b929","errorCode":null,"errorMessage":"Agent Failure - Run terminated: {run.Status} [{run.Id}]: {run.LastError?.Message ?? \"Unknown\"}","messagePattern":"Agent Failure - Run terminated: (.+?) \\[(.+?)\\]: (.+?)","errorType":"exception","errorClass":"KernelException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Agents/OpenAI/Internal/AssistantThreadActions.cs","lineNumber":164,"sourceCode":"        FunctionCallsProcessor functionProcessor = new(logger);\n        // This matches current behavior.  Will be configurable upon integrating with `FunctionChoice` (#6795/#5200)\n        FunctionChoiceBehaviorOptions functionOptions = new() { AllowConcurrentInvocation = true, AllowParallelCalls = true };\n\n        // Evaluate status and process steps and messages, as encountered.\n        HashSet<string> processedStepIds = [];\n        Dictionary<string, FunctionResultContent> functionSteps = [];\n        do\n        {\n            // Check for cancellation\n            cancellationToken.ThrowIfCancellationRequested();\n\n            // Poll run and steps until actionable\n            await PollRunStatusAsync().ConfigureAwait(false);\n\n            // Is in terminal state?\n            if (run.Status.IsTerminal && run.Status != RunStatus.Completed)\n            {\n                throw new KernelException($\"Agent Failure - Run terminated: {run.Status} [{run.Id}]: {run.LastError?.Message ?? \"Unknown\"}\");\n            }\n\n            List<RunStep> steps = [];\n            await foreach (var step in client.GetRunStepsAsync(run.ThreadId, run.Id, cancellationToken: cancellationToken).ConfigureAwait(false))\n            {\n                steps.Add(step);\n            }\n\n            // Is tool action required?\n            if (run.Status == RunStatus.RequiresAction)\n            {\n                logger.LogOpenAIAssistantProcessingRunSteps(nameof(InvokeAsync), run.Id, threadId);\n\n                // Execute functions in parallel and post results at once.\n                FunctionCallContent[] functionCalls = steps.SelectMany(step => ParseFunctionStep(agent, step)).ToArray();\n                if (functionCalls.Length > 0)\n                {\n                    // Emit function-call content","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/dotnet/src/Agents/OpenAI/Internal/AssistantThreadActions.cs#L146-L182","documentation":"In the non-streaming InvokeAsync loop, after each poll the run's status is checked; if it is terminal but not Completed (e.g., Failed, Cancelled, Expired, Incomplete), a KernelException is thrown carrying the run id, status, and last error message.","triggerScenarios":"An OpenAI assistant run ends in a non-success terminal state: a function tool threw, the run exceeded max iterations/tokens, it hit a content-policy block, rate limit, or expired before completing.","commonSituations":"A kernel function tool raises an exception the assistant surface treats as a run failure; long-running tools causing expiration; quota/rate-limit responses; malformed tool outputs.","solutions":["Inspect run.LastError.Message in the exception to find the root cause.","Make invoked function tools robust (catch internal errors, return a string result) so they don't fail the run.","Retry with exponential backoff for transient failures (rate limits, 5xx).","Increase run/timeout settings or reduce tool output size if the run expired or hit length limits."],"exampleFix":"// before\nawait foreach (var r in agent.InvokeAsync(thread)) { /* no error handling */ }\n// after\ntry {\n    await foreach (var r in agent.InvokeAsync(thread)) { /* ... */ }\n}\ncatch (KernelException ex) when (ex.Message.Contains(\"Run terminated\")) {\n    logger.LogError(ex, \"Assistant run failed; retrying\");\n    await Task.Delay(backoff);\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"int attempts = 0;\nretry:\ntry { await foreach (var r in agent.InvokeAsync(thread)) { /* ... */ } }\ncatch (KernelException ex) when (ex.Message.Contains(\"Run terminated\") && attempts++ < 3) {\n    await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, attempts)));\n    goto retry;\n}","preventionTips":["Make function tools return error strings instead of throwing.","Cap tool output size to avoid length-limit failures.","Log run.LastError.Message for every failure to find recurring causes.","Set reasonable run timeouts/iteration limits."],"tags":["openai","assistant-run","network","tool-error"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}