n8n-io/n8n · error · NodeOperationError

${error.message}

Error message

${error.message}

What it means

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.

Source

Thrown at packages/@n8n/nodes-langchain/nodes/vendors/Microsoft/microsoft-utils.ts:702

					activityCapture.output.push(activityOrText.text);
				}
				return await originalSendActivity(activityOrText);
			};

			turnContext.sendActivity = sendActivityWrapper;

			const onActivity = configureActivityCallback(
				nodeContext,
				credentials,
				mcpTokenRef,
				agent.authorization,
				activityCapture,
			);
			agent.onActivity(ActivityTypes.Message, onActivity, ['agentic']);

			await agent.run(turnContext);
		} catch (error) {
			throw new NodeOperationError(nodeContext.getNode(), error);
		} finally {
			if (observability) {
				try {
					const OBSERVABILITY_SHUTDOWN_TIMEOUT_MS = 5000;
					await Promise.race([
						observability.shutdown(),
						new Promise<never>((_, reject) =>
							setTimeout(
								() => reject(new Error('Observability shutdown timed out')),
								OBSERVABILITY_SHUTDOWN_TIMEOUT_MS,
							),
						),
					]);
				} catch (error) {
					// Backend unreachable or export timed out — not a code error
					console.warn('Failed to shut down observability:', error);
				}
			}

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Read error.message (and error.cause if present) on the thrown NodeOperationError to find the underlying agent.run failure.
  2. Check connectivity and credentials for every MCP server attached to the agent and for the LLM endpoint.
  3. Verify the authorization/turnContext are still valid for the full duration of the turn (no mid-turn expiry).
  4. Reproduce with observability enabled to capture the trace up to the failure point.
  5. If the error is transient (rate limit, network), retry the turn after backoff.
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate agent prerequisites before running the turn.
function assertAgentReady(params: {
  agent: { run: (t: unknown) => Promise<unknown> };
  turnContext: TurnContext;
  authorization: Authorization;
  mcpServers: MCPServerConfig[];
}): string | null {
  const { agent, turnContext, mcpServers } = params;
  if (typeof agent.run !== 'function') return 'Agent is missing a run() function';
  if (!turnContext?.activity) return 'turnContext.activity is missing — nothing to run on';
  if (mcpServers.length === 0) return 'No MCP servers attached; agent has no tools';
  return null;
}

const problem = assertAgentReady({ agent, turnContext, authorization, mcpServers });
if (problem) throw new NodeOperationError(nodeContext.getNode(), problem);

Type guard

function isRunnableAgent(a: unknown): a is { run: (t: TurnContext) => Promise<unknown> } {
  return !!a && typeof a === 'object' && typeof (a as { run?: unknown }).run === 'function';
}

Try / catch

try {
  await agent.run(turnContext);
} catch (error) {
  // Preserve the original cause so the UI shows both the wrapper and the root.
  throw new NodeOperationError(
    nodeContext.getNode(),
    error instanceof Error ? error.message : String(error),
    { cause: error },
  );
}

Prevention

When it happens

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

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

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/51791e5a11d8d528. Report an issue: GitHub.