Repository: n8n-io/n8n
File: packages/frontend/editor-ui/src/features/ai/assistant/composables/useAIAssistantHelpers.ts (TypeScript)

Code before:
			default:
				return undefined;
		}
	}
	/**
	 * Prepare workflow execution result data for the AI assistant
	 * by removing data from nodes
	 * @param data The execution result data to simplify
	 * @param options Options for simplification
	 * @param options.compact If true, removes large inputOverride fields (> 2000 bytes)
	 * @param options.removeParameterValues If true, removes parameter values but keeps errors (simplified) and metadata
	 **/
	function simplifyResultData(
		data: IRunExecutionData['resultData'],
		options: { compact?: boolean; removeParameterValues?: boolean } = {},
	): ChatRequest.ExecutionResultData {
		const { compact = false, removeParameterValues = false } = options;
		const simplifiedResultData: ChatRequest.ExecutionResultData = {
			runData: {},
		};

		// Handle optional error
		// When removeParameterValues is true, simplify the error to safe fields only (no node parameters)
		// This allows debugging while protecting sensitive data
		if (data.error) {
			if (removeParameterValues) {
				// Extract only safe fields from the error for debugging
				simplifiedResultData.error = {
					message: data.error.message,
					name: data.error.name,
					stack: data.error.stack,
				} as typeof data.error;
			} else {
				simplifiedResultData.error = data.error;
			}
		}

		// Early return if runData is not present
		if (!data.runData) {
			return simplifiedResultData;
		}

		// Map runData, excluding the `data` field from ITaskData
		for (const key of Object.keys(data.runData)) {
			const taskDataArray = data.runData[key];
			simplifiedResultData.runData[key] = taskDataArray.map((taskData) => {
				const { data: _taskDataContent, ...taskDataWithoutData } = taskData;

				// When privacy is OFF (removeParameterValues), always remove inputOverride
				// as it can contain parameter values
				if (removeParameterValues) {

Review comment (refactor):
do we need to simplify the error object? error.messages can have context. error.node is useful context where error happened and related parameters.

Code after:
			default:
				return undefined;
		}
	}
	/**
	 * Prepare workflow execution result data for the AI assistant
	 * by removing data from nodes
	 * @param data The execution result data to simplify
	 * @param options Options for simplification
	 * @param options.compact If true, removes large inputOverride fields (> 2000 bytes)
	 * @param options.removeParameterValues If true, removes parameter values but keeps errors and metadata
	 **/
	function simplifyResultData(
		data: IRunExecutionData['resultData'],
		options: { compact?: boolean; removeParameterValues?: boolean } = {},
	): ChatRequest.ExecutionResultData {
		const { compact = false, removeParameterValues = false } = options;
		const simplifiedResultData: ChatRequest.ExecutionResultData = {
			runData: {},
		};

		// Handle optional error - always pass through the full error for debugging context
		if (data.error) {
			simplifiedResultData.error = data.error;
		}

		// Early return if runData is not present
		if (!data.runData) {
			return simplifiedResultData;
		}

		// Map runData, excluding the `data` field from ITaskData
		for (const key of Object.keys(data.runData)) {
			const taskDataArray = data.runData[key];
			simplifiedResultData.runData[key] = taskDataArray.map((taskData) => {
				const { data: _taskDataContent, ...taskDataWithoutData } = taskData;

				// When privacy is OFF (removeParameterValues), always remove inputOverride
				// as it can contain parameter values
				if (removeParameterValues) {
					delete taskDataWithoutData.inputOverride;
				} else if (compact && taskDataWithoutData.inputOverride) {
					// If compact mode is enabled, remove large inputOverride fields
					try {
						const inputOverrideStr = JSON.stringify(taskDataWithoutData.inputOverride);
						const sizeInBytes = new Blob([inputOverrideStr]).size;

						// If too large, remove inputOverride entirely to maintain type safety
						if (sizeInBytes > 2000) {
							delete taskDataWithoutData.inputOverride;
						}