skills/aixier/n8n-automation-hub/n8n-best-practices

n8n-best-practices

SKILL.md

n8n Best Practices

When to use this skill: Any time you're working with n8n workflows and encounter errors, unexpected behavior, or need guidance on implementation patterns.

Critical Knowledge Base

🚨 ES5 Syntax Only in Code Nodes

n8n Code nodes only support ES5 JavaScript. Modern ES6+ syntax will fail.

❌ DO NOT USE:

// Arrow functions
const process = (item) => item.value;

// Template literals
const url = `https://api.example.com/${id}`;

// const/let
const value = 123;

// Destructuring
const { name, age } = person;

// Spread operator in function calls
Math.max(...numbers);

✅ USE INSTEAD:

// Regular functions
var process = function(item) {
  return item.value;
};

// String concatenation
var url = 'https://api.example.com/' + id;

// var only
var value = 123;

// Manual assignment
var name = person.name;
var age = person.age;

// apply() for spread
Math.max.apply(null, numbers);

// Object spread alternative
var merged = Object.assign({}, obj1, obj2);

🌐 HTTP Requests in Code Nodes

CRITICAL: $http and axios are NOT available in Code nodes.

❌ WRONG:

const response = await $http.request({url: 'https://api.example.com'});
const axios = require('axios');

✅ CORRECT - Use Native HTTPS:

var https = require('https');

function makeRequest(url, options) {
  return new Promise(function(resolve, reject) {
    var req = https.request(options, function(res) {
      var data = '';
      res.on('data', function(chunk) { data += chunk; });
      res.on('end', function() {
        resolve({statusCode: res.statusCode, body: data});
      });
    });
    req.on('error', reject);
    req.end();
  });
}

// Usage
var result = await makeRequest('example.com', {
  hostname: 'example.com',
  path: '/api/endpoint',
  method: 'POST',
  headers: {'Content-Type': 'application/json'}
});

🔐 Environment Variables Configuration

CRITICAL: Variables must be explicitly exported, not just sourced.

❌ WRONG:

source .env.local
pnpm start
# Variables will be undefined in Code nodes!

✅ CORRECT:

#!/bin/bash
export NOTION_API_KEY=$(grep NOTION_API_KEY .env.local | cut -d '=' -f2)
export QWEN_API_KEY=$(grep QWEN_API_KEY .env.local | cut -d '=' -f2)
export NODE_FUNCTION_ALLOW_BUILTIN=*
export N8N_BLOCK_ENV_ACCESS_IN_NODE=false
pnpm start

Access in Code nodes:

var apiKey = process.env.NOTION_API_KEY;  // Not $env

📦 gzip Compression Issues

Problem: HTTP requests with gzip compression return garbled data.

❌ WRONG:

headers: {
  'Accept-Encoding': 'gzip, deflate'
}
// Returns: �������

✅ CORRECT:

headers: {
  'Content-Type': 'application/json'
  // DO NOT include Accept-Encoding header
}

🔄 Data Flow Patterns

Always preserve upstream data:

✅ CORRECT:

return {
  json: Object.assign({}, $input.item.json, {
    newField: newValue
  })
};

❌ WRONG:

return {
  json: {
    newField: newValue  // Loses all previous data!
  }
};

📋 JSON Parsing Best Practices

❌ WRONG:

var data = JSON.parse(response);
// May return undefined without error

✅ CORRECT:

function safeJSONParse(text) {
  try {
    var parsed = JSON.parse(text);
    if (parsed && typeof parsed === 'object') {
      return parsed;
    }
    throw new Error('Parsed value is not an object');
  } catch (e) {
    throw new Error('JSON parsing failed: ' + e.message);
  }
}

var data = safeJSONParse(response);

🔧 Code Node Sandbox Configuration

macOS launchd service:

<key>EnvironmentVariables</key>
<dict>
  <key>NODE_FUNCTION_ALLOW_BUILTIN</key>
  <string>*</string>
</dict>

Shell script:

export NODE_FUNCTION_ALLOW_BUILTIN=*
n8n start

🐛 Common Pitfalls

1. Aggregate Node Array Wrapping

// Aggregate converts: {field: value} → {field: [value]}
var data = $input.first().json;
var actualValue = data.field[0];  // Must access array

2. Split Into Batches Data Loss

// ❌ WRONG: Loses data
return items.map(function(item) {
  return {json: {processed: true}};
});

// ✅ CORRECT: Preserves data
return items.map(function(item) {
  return {
    json: Object.assign({}, item.json, {processed: true})
  };
});

3. require() Module Access

// Only available if NODE_FUNCTION_ALLOW_BUILTIN=*
var https = require('https');  // ✅ Works
var axios = require('axios');  // ❌ Not available

Quick Reference

When Code node fails:

  1. Check ES5 syntax (no arrow functions, template literals)
  2. Verify environment variables are exported
  3. Use require('https') not $http
  4. Remove Accept-Encoding header for gzip issues

When data is lost:

  1. Always spread previous data: Object.assign({}, $input.item.json, newData)
  2. Check Aggregate node array wrapping
  3. Verify Split Into Batches preserves data

When environment variables are undefined:

  1. Use export, not source
  2. Access with process.env.VAR, not $env.VAR
  3. Set N8N_BLOCK_ENV_ACCESS_IN_NODE=false

Full Documentation

For complete details, examples, and advanced patterns, see: /mnt/d/work/n8n_agent/n8n-skills/n8n-best-practices/README.md

Weekly Installs
1
First Seen
9 days ago
Installed on
amp1
cline1
opencode1
cursor1
kimi-cli1
codex1