{"record":{"id":"51791e5a11d8d528","repo":"n8n-io/n8n","slug":"error-message-51791e","errorCode":null,"errorMessage":"${error.message}","messagePattern":"\\$\\{error\\.message\\}","errorType":"exception","errorClass":"NodeOperationError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/nodes-langchain/nodes/vendors/Microsoft/microsoft-utils.ts","lineNumber":702,"sourceCode":"\t\t\t\t\tactivityCapture.output.push(activityOrText.text);\n\t\t\t\t}\n\t\t\t\treturn await originalSendActivity(activityOrText);\n\t\t\t};\n\n\t\t\tturnContext.sendActivity = sendActivityWrapper;\n\n\t\t\tconst onActivity = configureActivityCallback(\n\t\t\t\tnodeContext,\n\t\t\t\tcredentials,\n\t\t\t\tmcpTokenRef,\n\t\t\t\tagent.authorization,\n\t\t\t\tactivityCapture,\n\t\t\t);\n\t\t\tagent.onActivity(ActivityTypes.Message, onActivity, ['agentic']);\n\n\t\t\tawait agent.run(turnContext);\n\t\t} catch (error) {\n\t\t\tthrow new NodeOperationError(nodeContext.getNode(), error);\n\t\t} finally {\n\t\t\tif (observability) {\n\t\t\t\ttry {\n\t\t\t\t\tconst OBSERVABILITY_SHUTDOWN_TIMEOUT_MS = 5000;\n\t\t\t\t\tawait Promise.race([\n\t\t\t\t\t\tobservability.shutdown(),\n\t\t\t\t\t\tnew Promise<never>((_, reject) =>\n\t\t\t\t\t\t\tsetTimeout(\n\t\t\t\t\t\t\t\t() => reject(new Error('Observability shutdown timed out')),\n\t\t\t\t\t\t\t\tOBSERVABILITY_SHUTDOWN_TIMEOUT_MS,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t]);\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// Backend unreachable or export timed out — not a code error\n\t\t\t\t\tconsole.warn('Failed to shut down observability:', error);\n\t\t\t\t}\n\t\t\t}","sourceCodeStart":684,"sourceCodeEnd":720,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/nodes-langchain/nodes/vendors/Microsoft/microsoft-utils.ts#L684-L720","documentation":"Top-level try/catch wrapping agent.run(turnContext) inside the Microsoft 365 Agent execution handler. Any error raised during the agent loop — LLM call, tool/MCP invocation, activity callback — is re-thrown as a NodeOperationError so n8n's execution engine surfaces it with node context. The finally block separately guards observability.shutdown() with its own 5s timeout, so this error specifically represents a failure inside the agent run itself, not the observability teardown.","triggerScenarios":"agent.run throws because: the LLM endpoint rejected the request (auth, quota, model unavailable); an MCP tool call returned an error the agent could not recover from; configureActivityCallback's onActivity handler threw inside the message pipeline; the turnContext activity payload was malformed; or the Bot Framework agent hit an internal assertion.","commonSituations":"Azure OpenAI / M365 LLM endpoint rate limiting or outage; MCP server unreachable mid-turn; malformed tool response from a community MCP server; token expired mid-conversation; agentic scope authorization revoked between turn start and tool call.","solutions":["Read error.message (and error.cause if present) on the thrown NodeOperationError to find the underlying agent.run failure.","Check connectivity and credentials for every MCP server attached to the agent and for the LLM endpoint.","Verify the authorization/turnContext are still valid for the full duration of the turn (no mid-turn expiry).","Reproduce with observability enabled to capture the trace up to the failure point.","If the error is transient (rate limit, network), retry the turn after backoff."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Validate agent prerequisites before running the turn.\nfunction assertAgentReady(params: {\n  agent: { run: (t: unknown) => Promise<unknown> };\n  turnContext: TurnContext;\n  authorization: Authorization;\n  mcpServers: MCPServerConfig[];\n}): string | null {\n  const { agent, turnContext, mcpServers } = params;\n  if (typeof agent.run !== 'function') return 'Agent is missing a run() function';\n  if (!turnContext?.activity) return 'turnContext.activity is missing — nothing to run on';\n  if (mcpServers.length === 0) return 'No MCP servers attached; agent has no tools';\n  return null;\n}\n\nconst problem = assertAgentReady({ agent, turnContext, authorization, mcpServers });\nif (problem) throw new NodeOperationError(nodeContext.getNode(), problem);","typeGuard":"function isRunnableAgent(a: unknown): a is { run: (t: TurnContext) => Promise<unknown> } {\n  return !!a && typeof a === 'object' && typeof (a as { run?: unknown }).run === 'function';\n}","tryCatchPattern":"try {\n  await agent.run(turnContext);\n} catch (error) {\n  // Preserve the original cause so the UI shows both the wrapper and the root.\n  throw new NodeOperationError(\n    nodeContext.getNode(),\n    error instanceof Error ? error.message : String(error),\n    { cause: error },\n  );\n}","preventionTips":["Always attach a cause when wrapping so the underlying agent.run failure is diagnosable.","Validate the LLM endpoint and every MCP server is reachable before starting the turn.","Keep observability enabled in non-production so the trace up to the failure is captured.","Refresh authorization immediately before long turns to avoid mid-run token expiry."],"tags":["agent","microsoft-365","runtime","wrapper","bot-framework"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}