N8n Instance Crashes When Custom Node Throws `NodeApiError` Or `NodeOperationError`

by ADMIN 84 views

Bug Description

When a custom node throws specific n8n error types like NodeApiError or NodeOperationError from within its execution logic, the entire n8n instance crashes unexpectedly. This behavior is not expected, as these error types should be caught by the n8n core, leading to a controlled node failure displayed within the n8n UI.

Expected Behavior

The NodeApiError and NodeOperationError should be caught by the n8n core, resulting in a controlled node failure displayed within the n8n UI. This would allow the workflow to continue based on error handling settings ("Continue on Fail"). Instead, the instance becomes unresponsive or terminates, requiring a restart.

To Reproduce

To reproduce this behavior, follow these steps:

Step 1: Create a Basic Custom n8n Node

Create a new custom n8n node by creating a new JavaScript file. For example, create a file named crashingNode.js with the following content:

const { NodeOperationError, INodeType, INodeExecutionData } = require('n8n-workflow');

class CrashingNode /* implements INodeType */ {
    description = {
        displayName: 'Crashing Node',
        name: 'crashingNode',
        group: ['transform'],
        version: 1,
        description: 'Throws NodeOperationError to test crash',
        defaults: {
            name: 'Crashing Node',
        },
        inputs: ['main'],
        outputs: ['main'],
        properties: []
    };

    async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
        const items = this.getInputData();
        let item;

        try {
            item = items[0]; // Assume at least one item for simplicity

            // Simulate an operation failure that should be caught by n8n
            console.log('About to throw NodeOperationError...');
            throw new NodeOperationError(this.getNode(), 'This is a simulated operation failure', { itemIndex: 0 });

            // This part will not be reached
            return this.prepareOutputData([item]);

        } catch (error) {
            // We expect n8n core to handle NodeOperationError, not this catch block
            // unless we were implementing a specific local try/catch.
            // If n8n itself crashes, this might not even be logged depending on the crash point.
            console.error('Caught error within execute (should not happen for NodeOperationError ideally):', error);
            // Re-throwing here might still cause a crash if the initial throw did
            throw error;
        }
    }
}

module.exports = {
    CrashingNode,
};

Step 2: Install the Custom Node in Your n8n Instance

Install the custom node in your n8n instance by running the following command:

n8n install /path/to/crashingNode.js

Step 3: Create a Simple Workflow Containing Only the CrashingNode

Create a new workflow in n8n and add the CrashingNode to it. Save the workflow.

Step 4: Execute the Workflow Manually

Execute the workflow manually by clicking the "Run" button.

Step 5: Observe the n8n Instance Crash

Observe that the n8n instance crashes or becomes unresponsive, instead of showing an error on the node in the UI. Check n8n logs for crash details if possible.

Expected Behavior

The CrashingNode should fail, displaying the "This is a simulated operation failure" error message in the n8n UI associated with the node. The n8n instance itself should remain operational.

Operating System

Ubuntu 22.04.3 LTS under WSL2 on Windows 10

n8n Version

1.81.4

Node.js Version

23.9.0

Database

SQLite (default)

Execution Mode

main (default)

Conclusion

Q: What is the expected behavior when a custom node throws NodeApiError or NodeOperationError?

A: The expected behavior is that the n8n core should catch these error types and display a controlled node failure in the n8n UI. This would allow the workflow to continue based on error handling settings ("Continue on Fail").

Q: Why is the n8n instance crashing when a custom node throws NodeApiError or NodeOperationError?

A: The n8n instance is crashing because the n8n core is not catching the NodeApiError or NodeOperationError and is instead propagating the error up the call stack, causing the instance to crash.

Q: How can I reproduce this issue?

A: To reproduce this issue, follow the steps outlined in the "To Reproduce" section of the original article. This includes creating a basic custom n8n node, installing it in your n8n instance, creating a simple workflow containing only the custom node, and executing the workflow manually.

Q: What are the system requirements for reproducing this issue?

A: The system requirements for reproducing this issue are:

  • Operating System: Ubuntu 22.04.3 LTS under WSL2 on Windows 10
  • n8n Version: 1.81.4
  • Node.js Version: 23.9.0
  • Database: SQLite (default)
  • Execution Mode: main (default)

Q: Can I use a different database or execution mode to reproduce this issue?

A: It is unlikely that you will be able to reproduce this issue using a different database or execution mode. The issue is specific to the n8n core and its handling of NodeApiError and NodeOperationError.

Q: How can I work around this issue?

A: One possible workaround is to throw standard Error objects instead of NodeApiError or NodeOperationError. However, this bypasses the intended specialized error handling provided by these classes.

Q: Is this issue specific to my n8n instance or is it a general issue with n8n?

A: This issue is likely a general issue with n8n and not specific to your n8n instance. However, it is possible that there are specific configurations or versions of n8n that are affected differently.

Q: How can I report this issue to the n8n developers?

A: You can report this issue to the n8n developers by creating a new issue on the n8n GitHub repository. Be sure to include as much detail as possible, including the steps to reproduce the issue and any relevant system information.