[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71430HCVZ2XCPW3Z3SW56G9":3,"skill-same:01M71430HCVZ2XCPW3Z3SW56G9":69},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":49,"commitSha":50,"skillDirectory":51,"forksCount":14,"repositoryHtmlUrl":52,"repositoryHomepageUrl":6,"ownerHtmlUrl":53,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":54,"install":55,"resources":68},"01M71430HCVZ2XCPW3Z3SW56G9","n8n-code-javascript",null,"Write JavaScript code in n8n Code nodes. Use when writing JavaScript in n8n, using $input\u002F$json\u002F$node syntax, making HTTP requests with $helpers, working with dates using DateTime, troubleshooting Code node errors, or choosing between Code node modes.","sapsapshen\u002Fai-memory-router","sapsapshen","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F20347959?v=4","01M6XDQEF1DP50DKF37H81J3J5","shenmian","01M6XDQEJPE41Y3DT2763X8ZJN",0,"MIT","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fcopilot\u002Fn8n-code-javascript\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"n8n code javascript","javascript","n8n","code","with","http","use","modes","dates","helpers","input","syntax","node","write","datetime","unknown","when","writing","errors","community","2026-11-10 10:12:30",false,"---\nname: n8n-code-javascript\ndescription: Write JavaScript code in n8n Code nodes. Use when writing JavaScript in n8n, using $input\u002F$json\u002F$node syntax, making HTTP requests with $helpers, working with dates using DateTime, troubleshooting Code node errors, or choosing between Code node modes.\nrisk: unknown\nsource: community\n---\n\n# JavaScript Code Node\n\nExpert guidance for writing JavaScript code in n8n Code nodes.\n\n---\n\n## Quick Start\n\n```javascript\n\u002F\u002F Basic template for Code nodes\nconst items = $input.all();\n\n\u002F\u002F Process data\nconst processed = items.map(item => ({\n  json: {\n    ...item.json,\n    processed: true,\n    timestamp: new Date().toISOString()\n  }\n}));\n\nreturn processed;\n```\n\n### Essential Rules\n\n1. **Choose \"Run Once for All Items\" mode** (recommended for most use cases)\n2. **Access data**: `$input.all()`, `$input.first()`, or `$input.item`\n3. **CRITICAL**: Must return `[{json: {...}}]` format\n4. **CRITICAL**: Webhook data is under `$json.body` (not `$json` directly)\n5. **Built-ins available**: $helpers.httpRequest(), DateTime (Luxon), $jmespath()\n\n---\n\n## Mode Selection Guide\n\nThe Code node offers two execution modes. Choose based on your use case:\n\n### Run Once for All Items (Recommended - Default)\n\n**Use this mode for:** 95% of use cases\n\n- **How it works**: Code executes **once** regardless of input count\n- **Data access**: `$input.all()` or `items` array\n- **Best for**: Aggregation, filtering, batch processing, transformations, API calls with all data\n- **Performance**: Faster for multiple items (single execution)\n\n```javascript\n\u002F\u002F Example: Calculate total from all items\nconst allItems = $input.all();\nconst total = allItems.reduce((sum, item) => sum + (item.json.amount || 0), 0);\n\nreturn [{\n  json: {\n    total,\n    count: allItems.length,\n    average: total \u002F allItems.length\n  }\n}];\n```\n\n**When to use:**\n- ✅ Comparing items across the dataset\n- ✅ Calculating totals, averages, or statistics\n- ✅ Sorting or ranking items\n- ✅ Deduplication\n- ✅ Building aggregated reports\n- ✅ Combining data from multiple items\n\n### Run Once for Each Item\n\n**Use this mode for:** Specialized cases only\n\n- **How it works**: Code executes **separately** for each input item\n- **Data access**: `$input.item` or `$item`\n- **Best for**: Item-specific logic, independent operations, per-item validation\n- **Performance**: Slower for large datasets (multiple executions)\n\n```javascript\n\u002F\u002F Example: Add processing timestamp to each item\nconst item = $input.item;\n\nreturn [{\n  json: {\n    ...item.json,\n    processed: true,\n    processedAt: new Date().toISOString()\n  }\n}];\n```\n\n**When to use:**\n- ✅ Each item needs independent API call\n- ✅ Per-item validation with different error handling\n- ✅ Item-specific transformations based on item properties\n- ✅ When items must be processed separately for business logic\n\n**Decision Shortcut:**\n- **Need to look at multiple items?** → Use \"All Items\" mode\n- **Each item completely independent?** → Use \"Each Item\" mode\n- **Not sure?** → Use \"All Items\" mode (you can always loop inside)\n\n---\n\n## Data Access Patterns\n\n### Pattern 1: $input.all() - Most Common\n\n**Use when**: Processing arrays, batch operations, aggregations\n\n```javascript\n\u002F\u002F Get all items from previous node\nconst allItems = $input.all();\n\n\u002F\u002F Filter, map, reduce as needed\nconst valid = allItems.filter(item => item.json.status === 'active');\nconst mapped = valid.map(item => ({\n  json: {\n    id: item.json.id,\n    name: item.json.name\n  }\n}));\n\nreturn mapped;\n```\n\n### Pattern 2: $input.first() - Very Common\n\n**Use when**: Working with single objects, API responses, first-in-first-out\n\n```javascript\n\u002F\u002F Get first item only\nconst firstItem = $input.first();\nconst data = firstItem.json;\n\nreturn [{\n  json: {\n    result: processData(data),\n    processedAt: new Date().toISOString()\n  }\n}];\n```\n\n### Pattern 3: $input.item - Each Item Mode Only\n\n**Use when**: In \"Run Once for Each Item\" mode\n\n```javascript\n\u002F\u002F Current item in loop (Each Item mode only)\nconst currentItem = $input.item;\n\nreturn [{\n  json: {\n    ...currentItem.json,\n    itemProcessed: true\n  }\n}];\n```\n\n### Pattern 4: $node - Reference Other Nodes\n\n**Use when**: Need data from specific nodes in workflow\n\n```javascript\n\u002F\u002F Get output from specific node\nconst webhookData = $node[\"Webhook\"].json;\nconst httpData = $node[\"HTTP Request\"].json;\n\nreturn [{\n  json: {\n    combined: {\n      webhook: webhookData,\n      api: httpData\n    }\n  }\n}];\n```\n\n**See**: DATA_ACCESS.md for comprehensive guide\n\n---\n\n## Critical: Webhook Data Structure\n\n**MOST COMMON MISTAKE**: Webhook data is nested under `.body`\n\n```javascript\n\u002F\u002F ❌ WRONG - Will return undefined\nconst name = $json.name;\nconst email = $json.email;\n\n\u002F\u002F ✅ CORRECT - Webhook data is under .body\nconst name = $json.body.name;\nconst email = $json.body.email;\n\n\u002F\u002F Or with $input\nconst webhookData = $input.first().json.body;\nconst name = webhookData.name;\n```\n\n**Why**: Webhook node wraps all request data under `body` property. This includes POST data, query parameters, and JSON payloads.\n\n**See**: DATA_ACCESS.md for full webhook structure details\n\n---\n\n## Return Format Requirements\n\n**CRITICAL RULE**: Always return array of objects with `json` property\n\n### Correct Return Formats\n\n```javascript\n\u002F\u002F ✅ Single result\nreturn [{\n  json: {\n    field1: value1,\n    field2: value2\n  }\n}];\n\n\u002F\u002F ✅ Multiple results\nreturn [\n  {json: {id: 1, data: 'first'}},\n  {json: {id: 2, data: 'second'}}\n];\n\n\u002F\u002F ✅ Transformed array\nconst transformed = $input.all()\n  .filter(item => item.json.valid)\n  .map(item => ({\n    json: {\n      id: item.json.id,\n      processed: true\n    }\n  }));\nreturn transformed;\n\n\u002F\u002F ✅ Empty result (when no data to return)\nreturn [];\n\n\u002F\u002F ✅ Conditional return\nif (shouldProcess) {\n  return [{json: processedData}];\n} else {\n  return [];\n}\n```\n\n### Incorrect Return Formats\n\n```javascript\n\u002F\u002F ❌ WRONG: Object without array wrapper\nreturn {\n  json: {field: value}\n};\n\n\u002F\u002F ❌ WRONG: Array without json wrapper\nreturn [{field: value}];\n\n\u002F\u002F ❌ WRONG: Plain string\nreturn \"processed\";\n\n\u002F\u002F ❌ WRONG: Raw data without mapping\nreturn $input.all();  \u002F\u002F Missing .map()\n\n\u002F\u002F ❌ WRONG: Incomplete structure\nreturn [{data: value}];  \u002F\u002F Should be {json: value}\n```\n\n**Why it matters**: Next nodes expect array format. Incorrect format causes workflow execution to fail.\n\n**See**: ERROR_PATTERNS.md #3 for detailed error solutions\n\n---\n\n## Common Patterns Overview\n\nBased on production workflows, here are the most useful patterns:\n\n### 1. Multi-Source Data Aggregation\nCombine data from multiple APIs, webhooks, or nodes\n\n```javascript\nconst allItems = $input.all();\nconst results = [];\n\nfor (const item of allItems) {\n  const sourceName = item.json.name || 'Unknown';\n  \u002F\u002F Parse source-specific structure\n  if (sourceName === 'API1' && item.json.data) {\n    results.push({\n      json: {\n        title: item.json.data.title,\n        source: 'API1'\n      }\n    });\n  }\n}\n\nreturn results;\n```\n\n### 2. Filtering with Regex\nExtract patterns, mentions, or keywords from text\n\n```javascript\nconst pattern = \u002F\\b([A-Z]{2,5})\\b\u002Fg;\nconst matches = {};\n\nfor (const item of $input.all()) {\n  const text = item.json.text;\n  const found = text.match(pattern);\n\n  if (found) {\n    found.forEach(match => {\n      matches[match] = (matches[match] || 0) + 1;\n    });\n  }\n}\n\nreturn [{json: {matches}}];\n```\n\n### 3. Data Transformation & Enrichment\nMap fields, normalize formats, add computed fields\n\n```javascript\nconst items = $input.all();\n\nreturn items.map(item => {\n  const data = item.json;\n  const nameParts = data.name.split(' ');\n\n  return {\n    json: {\n      first_name: nameParts[0],\n      last_name: nameParts.slice(1).join(' '),\n      email: data.email,\n      created_at: new Date().toISOString()\n    }\n  };\n});\n```\n\n### 4. Top N Filtering & Ranking\nSort and limit results\n\n```javascript\nconst items = $input.all();\n\nconst topItems = items\n  .sort((a, b) => (b.json.score || 0) - (a.json.score || 0))\n  .slice(0, 10);\n\nreturn topItems.map(item => ({json: item.json}));\n```\n\n### 5. Aggregation & Reporting\nSum, count, group data\n\n```javascript\nconst items = $input.all();\nconst total = items.reduce((sum, item) => sum + (item.json.amount || 0), 0);\n\nreturn [{\n  json: {\n    total,\n    count: items.length,\n    average: total \u002F items.length,\n    timestamp: new Date().toISOString()\n  }\n}];\n```\n\n**See**: COMMON_PATTERNS.md for 10 detailed production patterns\n\n---\n\n## Error Prevention - Top 5 Mistakes\n\n### #1: Empty Code or Missing Return (Most Common)\n\n```javascript\n\u002F\u002F ❌ WRONG: No return statement\nconst items = $input.all();\n\u002F\u002F ... processing code ...\n\u002F\u002F Forgot to return!\n\n\u002F\u002F ✅ CORRECT: Always return data\nconst items = $input.all();\n\u002F\u002F ... processing ...\nreturn items.map(item => ({json: item.json}));\n```\n\n### #2: Expression Syntax Confusion\n\n```javascript\n\u002F\u002F ❌ WRONG: Using n8n expression syntax in code\nconst value = \"{{ $json.field }}\";\n\n\u002F\u002F ✅ CORRECT: Use JavaScript template literals\nconst value = `${$json.field}`;\n\n\u002F\u002F ✅ CORRECT: Direct access\nconst value = $input.first().json.field;\n```\n\n### #3: Incorrect Return Wrapper\n\n```javascript\n\u002F\u002F ❌ WRONG: Returning object instead of array\nreturn {json: {result: 'success'}};\n\n\u002F\u002F ✅ CORRECT: Array wrapper required\nreturn [{json: {result: 'success'}}];\n```\n\n### #4: Missing Null Checks\n\n```javascript\n\u002F\u002F ❌ WRONG: Crashes if field doesn't exist\nconst value = item.json.user.email;\n\n\u002F\u002F ✅ CORRECT: Safe access with optional chaining\nconst value = item.json?.user?.email || 'no-email@example.com';\n\n\u002F\u002F ✅ CORRECT: Guard clause\nif (!item.json.user) {\n  return [];\n}\nconst value = item.json.user.email;\n```\n\n### #5: Webhook Body Nesting\n\n```javascript\n\u002F\u002F ❌ WRONG: Direct access to webhook data\nconst email = $json.email;\n\n\u002F\u002F ✅ CORRECT: Webhook data under .body\nconst email = $json.body.email;\n```\n\n**See**: ERROR_PATTERNS.md for comprehensive error guide\n\n---\n\n## Built-in Functions & Helpers\n\n### $helpers.httpRequest()\n\nMake HTTP requests from within code:\n\n```javascript\nconst response = await $helpers.httpRequest({\n  method: 'GET',\n  url: 'https:\u002F\u002Fapi.example.com\u002Fdata',\n  headers: {\n    'Authorization': 'Bearer token',\n    'Content-Type': 'application\u002Fjson'\n  }\n});\n\nreturn [{json: {data: response}}];\n```\n\n### DateTime (Luxon)\n\nDate and time operations:\n\n```javascript\n\u002F\u002F Current time\nconst now = DateTime.now();\n\n\u002F\u002F Format dates\nconst formatted = now.toFormat('yyyy-MM-dd');\nconst iso = now.toISO();\n\n\u002F\u002F Date arithmetic\nconst tomorrow = now.plus({days: 1});\nconst lastWeek = now.minus({weeks: 1});\n\nreturn [{\n  json: {\n    today: formatted,\n    tomorrow: tomorrow.toFormat('yyyy-MM-dd')\n  }\n}];\n```\n\n### $jmespath()\n\nQuery JSON structures:\n\n```javascript\nconst data = $input.first().json;\n\n\u002F\u002F Filter array\nconst adults = $jmespath(data, 'users[?age >= `18`]');\n\n\u002F\u002F Extract fields\nconst names = $jmespath(data, 'users[*].name');\n\nreturn [{json: {adults, names}}];\n```\n\n**See**: BUILTIN_FUNCTIONS.md for complete reference\n\n---\n\n## Best Practices\n\n### 1. Always Validate Input Data\n\n```javascript\nconst items = $input.all();\n\n\u002F\u002F Check if data exists\nif (!items || items.length === 0) {\n  return [];\n}\n\n\u002F\u002F Validate structure\nif (!items[0].json) {\n  return [{json: {error: 'Invalid input format'}}];\n}\n\n\u002F\u002F Continue processing...\n```\n\n### 2. Use Try-Catch for Error Handling\n\n```javascript\ntry {\n  const response = await $helpers.httpRequest({\n    url: 'https:\u002F\u002Fapi.example.com\u002Fdata'\n  });\n\n  return [{json: {success: true, data: response}}];\n} catch (error) {\n  return [{\n    json: {\n      success: false,\n      error: error.message\n    }\n  }];\n}\n```\n\n### 3. Prefer Array Methods Over Loops\n\n```javascript\n\u002F\u002F ✅ GOOD: Functional approach\nconst processed = $input.all()\n  .filter(item => item.json.valid)\n  .map(item => ({json: {id: item.json.id}}));\n\n\u002F\u002F ❌ SLOWER: Manual loop\nconst processed = [];\nfor (const item of $input.all()) {\n  if (item.json.valid) {\n    processed.push({json: {id: item.json.id}});\n  }\n}\n```\n\n### 4. Filter Early, Process Late\n\n```javascript\n\u002F\u002F ✅ GOOD: Filter first to reduce processing\nconst processed = $input.all()\n  .filter(item => item.json.status === 'active')  \u002F\u002F Reduce dataset first\n  .map(item => expensiveTransformation(item));  \u002F\u002F Then transform\n\n\u002F\u002F ❌ WASTEFUL: Transform everything, then filter\nconst processed = $input.all()\n  .map(item => expensiveTransformation(item))  \u002F\u002F Wastes CPU\n  .filter(item => item.json.status === 'active');\n```\n\n### 5. Use Descriptive Variable Names\n\n```javascript\n\u002F\u002F ✅ GOOD: Clear intent\nconst activeUsers = $input.all().filter(item => item.json.active);\nconst totalRevenue = activeUsers.reduce((sum, user) => sum + user.json.revenue, 0);\n\n\u002F\u002F ❌ BAD: Unclear purpose\nconst a = $input.all().filter(item => item.json.active);\nconst t = a.reduce((s, u) => s + u.json.revenue, 0);\n```\n\n### 6. Debug with console.log()\n\n```javascript\n\u002F\u002F Debug statements appear in browser console\nconst items = $input.all();\nconsole.log(`Processing ${items.length} items`);\n\nfor (const item of items) {\n  console.log('Item data:', item.json);\n  \u002F\u002F Process...\n}\n\nreturn result;\n```\n\n---\n\n## When to Use Code Node\n\nUse Code node when:\n- ✅ Complex transformations requiring multiple steps\n- ✅ Custom calculations or business logic\n- ✅ Recursive operations\n- ✅ API response parsing with complex structure\n- ✅ Multi-step conditionals\n- ✅ Data aggregation across items\n\nConsider other nodes when:\n- ❌ Simple field mapping → Use **Set** node\n- ❌ Basic filtering → Use **Filter** node\n- ❌ Simple conditionals → Use **IF** or **Switch** node\n- ❌ HTTP requests only → Use **HTTP Request** node\n\n**Code node excels at**: Complex logic that would require chaining many simple nodes\n\n---\n\n## Integration with Other Skills\n\n### Works With:\n\n**n8n Expression Syntax**:\n- Expressions use `{{ }}` syntax in other nodes\n- Code nodes use JavaScript directly (no `{{ }}`)\n- When to use expressions vs code\n\n**n8n MCP Tools Expert**:\n- How to find Code node: `search_nodes({query: \"code\"})`\n- Get configuration help: `get_node_essentials(\"nodes-base.code\")`\n- Validate code: `validate_node_operation()`\n\n**n8n Node Configuration**:\n- Mode selection (All Items vs Each Item)\n- Language selection (JavaScript vs Python)\n- Understanding property dependencies\n\n**n8n Workflow Patterns**:\n- Code nodes in transformation step\n- Webhook → Code → API pattern\n- Error handling in workflows\n\n**n8n Validation Expert**:\n- Validate Code node configuration\n- Handle validation errors\n- Auto-fix common issues\n\n---\n\n## Quick Reference Checklist\n\nBefore deploying Code nodes, verify:\n\n- [ ] **Code is not empty** - Must have meaningful logic\n- [ ] **Return statement exists** - Must return array of objects\n- [ ] **Proper return format** - Each item: `{json: {...}}`\n- [ ] **Data access correct** - Using `$input.all()`, `$input.first()`, or `$input.item`\n- [ ] **No n8n expressions** - Use JavaScript template literals: `` `${value}` ``\n- [ ] **Error handling** - Guard clauses for null\u002Fundefined inputs\n- [ ] **Webhook data** - Access via `.body` if from webhook\n- [ ] **Mode selection** - \"All Items\" for most cases\n- [ ] **Performance** - Prefer map\u002Ffilter over manual loops\n- [ ] **Output consistent** - All code paths return same structure\n\n---\n\n## Additional Resources\n\n### Related Files\n- DATA_ACCESS.md - Comprehensive data access patterns\n- COMMON_PATTERNS.md - 10 production-tested patterns\n- ERROR_PATTERNS.md - Top 5 errors and solutions\n- BUILTIN_FUNCTIONS.md - Complete built-in reference\n\n### n8n Documentation\n- Code Node Guide: https:\u002F\u002Fdocs.n8n.io\u002Fcode\u002Fcode-node\u002F\n- Built-in Methods: https:\u002F\u002Fdocs.n8n.io\u002Fcode-examples\u002Fmethods-variables-reference\u002F\n- Luxon Documentation: https:\u002F\u002Fmoment.github.io\u002Fluxon\u002F\n\n---\n\n**Ready to write JavaScript in n8n Code nodes!** Start with simple transformations, use the error patterns guide to avoid common mistakes, and reference the pattern library for production-ready examples.\n","# JavaScript Code Node\n\nExpert guidance for writing JavaScript code in n8n Code nodes.\n\n---\n\n## Quick Start\n\n```javascript\n\u002F\u002F Basic template for Code nodes\nconst items = $input.all();\n\n\u002F\u002F Process data\nconst processed = items.map(item => ({\n  json: {\n    ...item.json,\n    processed: true,\n    timestamp: new Date().toISOString()\n  }\n}));\n\nreturn processed;\n```\n\n### Essential Rules\n\n1. **Choose \"Run Once for All Items\" mode** (recommended for most use cases)\n2. **Access data**: `$input.all()`, `$input.first()`, or `$input.item`\n3. **CRITICAL**: Must return `[{json: {...}}]` format\n4. **CRITICAL**: Webhook data is under `$json.body` (not `$json` directly)\n5. **Built-ins available**: $helpers.httpRequest(), DateTime (Luxon), $jmespath()\n\n---\n\n## Mode Selection Guide\n\nThe Code node offers two execution modes. Choose based on your use case:\n\n### Run Once for All Items (Recommended - Default)\n\n**Use this mode for:** 95% of use cases\n\n- **How it works**: Code executes **once** regardless of input count\n- **Data access**: `$input.all()` or `items` array\n- **Best for**: Aggregation, filtering, batch processing, transformations, API calls with all data\n- **Performance**: Faster for multiple items (single execution)\n\n```javascript\n\u002F\u002F Example: Calculate total from all items\nconst allItems = $input.all();\nconst total = allItems.reduce((sum, item) => sum + (item.json.amount || 0), 0);\n\nreturn [{\n  json: {\n    total,\n    count: allItems.length,\n    average: total \u002F allItems.length\n  }\n}];\n```\n\n**When to use:**\n- ✅ Comparing items across the dataset\n- ✅ Calculating totals, averages, or statistics\n- ✅ Sorting or ranking items\n- ✅ Deduplication\n- ✅ Building aggregated reports\n- ✅ Combining data from multiple items\n\n### Run Once for Each Item\n\n**Use this mode for:** Specialized cases only\n\n- **How it works**: Code executes **separately** for each input item\n- **Data access**: `$input.item` or `$item`\n- **Best for**: Item-specific logic, independent operations, per-item validation\n- **Performance**: Slower for large datasets (multiple executions)\n\n```javascript\n\u002F\u002F Example: Add processing timestamp to each item\nconst item = $input.item;\n\nreturn [{\n  json: {\n    ...item.json,\n    processed: true,\n    processedAt: new Date().toISOString()\n  }\n}];\n```\n\n**When to use:**\n- ✅ Each item needs independent API call\n- ✅ Per-item validation with different error handling\n- ✅ Item-specific transformations based on item properties\n- ✅ When items must be processed separately for business logic\n\n**Decision Shortcut:**\n- **Need to look at multiple items?** → Use \"All Items\" mode\n- **Each item completely independent?** → Use \"Each Item\" mode\n- **Not sure?** → Use \"All Items\" mode (you can always loop inside)\n\n---\n\n## Data Access Patterns\n\n### Pattern 1: $input.all() - Most Common\n\n**Use when**: Processing arrays, batch operations, aggregations\n\n```javascript\n\u002F\u002F Get all items from previous node\nconst allItems = $input.all();\n\n\u002F\u002F Filter, map, reduce as needed\nconst valid = allItems.filter(item => item.json.status === 'active');\nconst mapped = valid.map(item => ({\n  json: {\n    id: item.json.id,\n    name: item.json.name\n  }\n}));\n\nreturn mapped;\n```\n\n### Pattern 2: $input.first() - Very Common\n\n**Use when**: Working with single objects, API responses, first-in-first-out\n\n```javascript\n\u002F\u002F Get first item only\nconst firstItem = $input.first();\nconst data = firstItem.json;\n\nreturn [{\n  json: {\n    result: processData(data),\n    processedAt: new Date().toISOString()\n  }\n}];\n```\n\n### Pattern 3: $input.item - Each Item Mode Only\n\n**Use when**: In \"Run Once for Each Item\" mode\n\n```javascript\n\u002F\u002F Current item in loop (Each Item mode only)\nconst currentItem = $input.item;\n\nreturn [{\n  json: {\n    ...currentItem.json,\n    itemProcessed: true\n  }\n}];\n```\n\n### Pattern 4: $node - Reference Other Nodes\n\n**Use when**: Need data from specific nodes in workflow\n\n```javascript\n\u002F\u002F Get output from specific node\nconst webhookData = $node[\"Webhook\"].json;\nconst httpData = $node[\"HTTP Request\"].json;\n\nreturn [{\n  json: {\n    combined: {\n      webhook: webhookData,\n      api: httpData\n    }\n  }\n}];\n```\n\n**See**: DATA_ACCESS.md for comprehensive guide\n\n---\n\n## Critical: Webhook Data Structure\n\n**MOST COMMON MISTAKE**: Webhook data is nested under `.body`\n\n```javascript\n\u002F\u002F ❌ WRONG - Will return undefined\nconst name = $json.name;\nconst email = $json.email;\n\n\u002F\u002F ✅ CORRECT - Webhook data is under .body\nconst name = $json.body.name;\nconst email = $json.body.email;\n\n\u002F\u002F Or with $input\nconst webhookData = $input.first().json.body;\nconst name = webhookData.name;\n```\n\n**Why**: Webhook node wraps all request data under `body` property. This includes POST data, query parameters, and JSON payloads.\n\n**See**: DATA_ACCESS.md for full webhook structure details\n\n---\n\n## Return Format Requirements\n\n**CRITICAL RULE**: Always return array of objects with `json` property\n\n### Correct Return Formats\n\n```javascript\n\u002F\u002F ✅ Single result\nreturn [{\n  json: {\n    field1: value1,\n    field2: value2\n  }\n}];\n\n\u002F\u002F ✅ Multiple results\nreturn [\n  {json: {id: 1, data: 'first'}},\n  {json: {id: 2, data: 'second'}}\n];\n\n\u002F\u002F ✅ Transformed array\nconst transformed = $input.all()\n  .filter(item => item.json.valid)\n  .map(item => ({\n    json: {\n      id: item.json.id,\n      processed: true\n    }\n  }));\nreturn transformed;\n\n\u002F\u002F ✅ Empty result (when no data to return)\nreturn [];\n\n\u002F\u002F ✅ Conditional return\nif (shouldProcess) {\n  return [{json: processedData}];\n} else {\n  return [];\n}\n```\n\n### Incorrect Return Formats\n\n```javascript\n\u002F\u002F ❌ WRONG: Object without array wrapper\nreturn {\n  json: {field: value}\n};\n\n\u002F\u002F ❌ WRONG: Array without json wrapper\nreturn [{field: value}];\n\n\u002F\u002F ❌ WRONG: Plain string\nreturn \"processed\";\n\n\u002F\u002F ❌ WRONG: Raw data without mapping\nreturn $input.all();  \u002F\u002F Missing .map()\n\n\u002F\u002F ❌ WRONG: Incomplete structure\nreturn [{data: value}];  \u002F\u002F Should be {json: value}\n```\n\n**Why it matters**: Next nodes expect array format. Incorrect format causes workflow execution to fail.\n\n**See**: ERROR_PATTERNS.md #3 for detailed error solutions\n\n---\n\n## Common Patterns Overview\n\nBased on production workflows, here are the most useful patterns:\n\n### 1. Multi-Source Data Aggregation\nCombine data from multiple APIs, webhooks, or nodes\n\n```javascript\nconst allItems = $input.all();\nconst results = [];\n\nfor (const item of allItems) {\n  const sourceName = item.json.name || 'Unknown';\n  \u002F\u002F Parse source-specific structure\n  if (sourceName === 'API1' && item.json.data) {\n    results.push({\n      json: {\n        title: item.json.data.title,\n        source: 'API1'\n      }\n    });\n  }\n}\n\nreturn results;\n```\n\n### 2. Filtering with Regex\nExtract patterns, mentions, or keywords from text\n\n```javascript\nconst pattern = \u002F\\b([A-Z]{2,5})\\b\u002Fg;\nconst matches = {};\n\nfor (const item of $input.all()) {\n  const text = item.json.text;\n  const found = text.match(pattern);\n\n  if (found) {\n    found.forEach(match => {\n      matches[match] = (matches[match] || 0) + 1;\n    });\n  }\n}\n\nreturn [{json: {matches}}];\n```\n\n### 3. Data Transformation & Enrichment\nMap fields, normalize formats, add computed fields\n\n```javascript\nconst items = $input.all();\n\nreturn items.map(item => {\n  const data = item.json;\n  const nameParts = data.name.split(' ');\n\n  return {\n    json: {\n      first_name: nameParts[0],\n      last_name: nameParts.slice(1).join(' '),\n      email: data.email,\n      created_at: new Date().toISOString()\n    }\n  };\n});\n```\n\n### 4. Top N Filtering & Ranking\nSort and limit results\n\n```javascript\nconst items = $input.all();\n\nconst topItems = items\n  .sort((a, b) => (b.json.score || 0) - (a.json.score || 0))\n  .slice(0, 10);\n\nreturn topItems.map(item => ({json: item.json}));\n```\n\n### 5. Aggregation & Reporting\nSum, count, group data\n\n```javascript\nconst items = $input.all();\nconst total = items.reduce((sum, item) => sum + (item.json.amount || 0), 0);\n\nreturn [{\n  json: {\n    total,\n    count: items.length,\n    average: total \u002F items.length,\n    timestamp: new Date().toISOString()\n  }\n}];\n```\n\n**See**: COMMON_PATTERNS.md for 10 detailed production patterns\n\n---\n\n## Error Prevention - Top 5 Mistakes\n\n### #1: Empty Code or Missing Return (Most Common)\n\n```javascript\n\u002F\u002F ❌ WRONG: No return statement\nconst items = $input.all();\n\u002F\u002F ... processing code ...\n\u002F\u002F Forgot to return!\n\n\u002F\u002F ✅ CORRECT: Always return data\nconst items = $input.all();\n\u002F\u002F ... processing ...\nreturn items.map(item => ({json: item.json}));\n```\n\n### #2: Expression Syntax Confusion\n\n```javascript\n\u002F\u002F ❌ WRONG: Using n8n expression syntax in code\nconst value = \"{{ $json.field }}\";\n\n\u002F\u002F ✅ CORRECT: Use JavaScript template literals\nconst value = `${$json.field}`;\n\n\u002F\u002F ✅ CORRECT: Direct access\nconst value = $input.first().json.field;\n```\n\n### #3: Incorrect Return Wrapper\n\n```javascript\n\u002F\u002F ❌ WRONG: Returning object instead of array\nreturn {json: {result: 'success'}};\n\n\u002F\u002F ✅ CORRECT: Array wrapper required\nreturn [{json: {result: 'success'}}];\n```\n\n### #4: Missing Null Checks\n\n```javascript\n\u002F\u002F ❌ WRONG: Crashes if field doesn't exist\nconst value = item.json.user.email;\n\n\u002F\u002F ✅ CORRECT: Safe access with optional chaining\nconst value = item.json?.user?.email || 'no-email@example.com';\n\n\u002F\u002F ✅ CORRECT: Guard clause\nif (!item.json.user) {\n  return [];\n}\nconst value = item.json.user.email;\n```\n\n### #5: Webhook Body Nesting\n\n```javascript\n\u002F\u002F ❌ WRONG: Direct access to webhook data\nconst email = $json.email;\n\n\u002F\u002F ✅ CORRECT: Webhook data under .body\nconst email = $json.body.email;\n```\n\n**See**: ERROR_PATTERNS.md for comprehensive error guide\n\n---\n\n## Built-in Functions & Helpers\n\n### $helpers.httpRequest()\n\nMake HTTP requests from within code:\n\n```javascript\nconst response = await $helpers.httpRequest({\n  method: 'GET',\n  url: 'https:\u002F\u002Fapi.example.com\u002Fdata',\n  headers: {\n    'Authorization': 'Bearer token',\n    'Content-Type': 'application\u002Fjson'\n  }\n});\n\nreturn [{json: {data: response}}];\n```\n\n### DateTime (Luxon)\n\nDate and time operations:\n\n```javascript\n\u002F\u002F Current time\nconst now = DateTime.now();\n\n\u002F\u002F Format dates\nconst formatted = now.toFormat('yyyy-MM-dd');\nconst iso = now.toISO();\n\n\u002F\u002F Date arithmetic\nconst tomorrow = now.plus({days: 1});\nconst lastWeek = now.minus({weeks: 1});\n\nreturn [{\n  json: {\n    today: formatted,\n    tomorrow: tomorrow.toFormat('yyyy-MM-dd')\n  }\n}];\n```\n\n### $jmespath()\n\nQuery JSON structures:\n\n```javascript\nconst data = $input.first().json;\n\n\u002F\u002F Filter array\nconst adults = $jmespath(data, 'users[?age >= `18`]');\n\n\u002F\u002F Extract fields\nconst names = $jmespath(data, 'users[*].name');\n\nreturn [{json: {adults, names}}];\n```\n\n**See**: BUILTIN_FUNCTIONS.md for complete reference\n\n---\n\n## Best Practices\n\n### 1. Always Validate Input Data\n\n```javascript\nconst items = $input.all();\n\n\u002F\u002F Check if data exists\nif (!items || items.length === 0) {\n  return [];\n}\n\n\u002F\u002F Validate structure\nif (!items[0].json) {\n  return [{json: {error: 'Invalid input format'}}];\n}\n\n\u002F\u002F Continue processing...\n```\n\n### 2. Use Try-Catch for Error Handling\n\n```javascript\ntry {\n  const response = await $helpers.httpRequest({\n    url: 'https:\u002F\u002Fapi.example.com\u002Fdata'\n  });\n\n  return [{json: {success: true, data: response}}];\n} catch (error) {\n  return [{\n    json: {\n      success: false,\n      error: error.message\n    }\n  }];\n}\n```\n\n### 3. Prefer Array Methods Over Loops\n\n```javascript\n\u002F\u002F ✅ GOOD: Functional approach\nconst processed = $input.all()\n  .filter(item => item.json.valid)\n  .map(item => ({json: {id: item.json.id}}));\n\n\u002F\u002F ❌ SLOWER: Manual loop\nconst processed = [];\nfor (const item of $input.all()) {\n  if (item.json.valid) {\n    processed.push({json: {id: item.json.id}});\n  }\n}\n```\n\n### 4. Filter Early, Process Late\n\n```javascript\n\u002F\u002F ✅ GOOD: Filter first to reduce processing\nconst processed = $input.all()\n  .filter(item => item.json.status === 'active')  \u002F\u002F Reduce dataset first\n  .map(item => expensiveTransformation(item));  \u002F\u002F Then transform\n\n\u002F\u002F ❌ WASTEFUL: Transform everything, then filter\nconst processed = $input.all()\n  .map(item => expensiveTransformation(item))  \u002F\u002F Wastes CPU\n  .filter(item => item.json.status === 'active');\n```\n\n### 5. Use Descriptive Variable Names\n\n```javascript\n\u002F\u002F ✅ GOOD: Clear intent\nconst activeUsers = $input.all().filter(item => item.json.active);\nconst totalRevenue = activeUsers.reduce((sum, user) => sum + user.json.revenue, 0);\n\n\u002F\u002F ❌ BAD: Unclear purpose\nconst a = $input.all().filter(item => item.json.active);\nconst t = a.reduce((s, u) => s + u.json.revenue, 0);\n```\n\n### 6. Debug with console.log()\n\n```javascript\n\u002F\u002F Debug statements appear in browser console\nconst items = $input.all();\nconsole.log(`Processing ${items.length} items`);\n\nfor (const item of items) {\n  console.log('Item data:', item.json);\n  \u002F\u002F Process...\n}\n\nreturn result;\n```\n\n---\n\n## When to Use Code Node\n\nUse Code node when:\n- ✅ Complex transformations requiring multiple steps\n- ✅ Custom calculations or business logic\n- ✅ Recursive operations\n- ✅ API response parsing with complex structure\n- ✅ Multi-step conditionals\n- ✅ Data aggregation across items\n\nConsider other nodes when:\n- ❌ Simple field mapping → Use **Set** node\n- ❌ Basic filtering → Use **Filter** node\n- ❌ Simple conditionals → Use **IF** or **Switch** node\n- ❌ HTTP requests only → Use **HTTP Request** node\n\n**Code node excels at**: Complex logic that would require chaining many simple nodes\n\n---\n\n## Integration with Other Skills\n\n### Works With:\n\n**n8n Expression Syntax**:\n- Expressions use `{{ }}` syntax in other nodes\n- Code nodes use JavaScript directly (no `{{ }}`)\n- When to use expressions vs code\n\n**n8n MCP Tools Expert**:\n- How to find Code node: `search_nodes({query: \"code\"})`\n- Get configuration help: `get_node_essentials(\"nodes-base.code\")`\n- Validate code: `validate_node_operation()`\n\n**n8n Node Configuration**:\n- Mode selection (All Items vs Each Item)\n- Language selection (JavaScript vs Python)\n- Understanding property dependencies\n\n**n8n Workflow Patterns**:\n- Code nodes in transformation step\n- Webhook → Code → API pattern\n- Error handling in workflows\n\n**n8n Validation Expert**:\n- Validate Code node configuration\n- Handle validation errors\n- Auto-fix common issues\n\n---\n\n## Quick Reference Checklist\n\nBefore deploying Code nodes, verify:\n\n- [ ] **Code is not empty** - Must have meaningful logic\n- [ ] **Return statement exists** - Must return array of objects\n- [ ] **Proper return format** - Each item: `{json: {...}}`\n- [ ] **Data access correct** - Using `$input.all()`, `$input.first()`, or `$input.item`\n- [ ] **No n8n expressions** - Use JavaScript template literals: `` `${value}` ``\n- [ ] **Error handling** - Guard clauses for null\u002Fundefined inputs\n- [ ] **Webhook data** - Access via `.body` if from webhook\n- [ ] **Mode selection** - \"All Items\" for most cases\n- [ ] **Performance** - Prefer map\u002Ffilter over manual loops\n- [ ] **Output consistent** - All code paths return same structure\n\n---\n\n## Additional Resources\n\n### Related Files\n- DATA_ACCESS.md - Comprehensive data access patterns\n- COMMON_PATTERNS.md - 10 production-tested patterns\n- ERROR_PATTERNS.md - Top 5 errors and solutions\n- BUILTIN_FUNCTIONS.md - Complete built-in reference\n\n### n8n Documentation\n- Code Node Guide: https:\u002F\u002Fdocs.n8n.io\u002Fcode\u002Fcode-node\u002F\n- Built-in Methods: https:\u002F\u002Fdocs.n8n.io\u002Fcode-examples\u002Fmethods-variables-reference\u002F\n- Luxon Documentation: https:\u002F\u002Fmoment.github.io\u002Fluxon\u002F\n\n---\n\n**Ready to write JavaScript in n8n Code nodes!** Start with simple transformations, use the error patterns guide to avoid common mistakes, and reference the pattern library for production-ready examples.\n",{"name":5,"risk":39,"source":43,"description":7},"main","7a38d8e7073e61c16eda85681cb32fb68a8657a5","skills-store\u002Fcopilot\u002Fn8n-code-javascript","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router","https:\u002F\u002Fgithub.com\u002Fsapsapshen","2026-04-14 21:12:12",{"source":8,"skillName":5,"commands":56,"prompt":66,"zipAvailable":67},[57,60,63],{"tool":58,"command":59},"npx","npx skills add sapsapshen\u002Fai-memory-router --skill n8n-code-javascript",{"tool":61,"command":62},"bunx","bunx skills add sapsapshen\u002Fai-memory-router --skill n8n-code-javascript",{"tool":64,"command":65},"pnpm","pnpm dlx skills add sapsapshen\u002Fai-memory-router --skill n8n-code-javascript","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fcopilot\u002Fn8n-code-javascript\u002FSKILL.md",true,[],[70,91,116,126,139,158],{"skillNo":71,"name":72,"nameZh":6,"description":73,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":74,"categories":75,"keywords":79,"publishedAt":44},"01M71ATQRKG48SH06FQ697T5G9","wechat-search","Search WeChat Official Account articles using OpenClaw's web search and fetch capabilities with compliance-focused design.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fwechat-search-release\u002FSKILL.md",[76],{"categoryNo":77,"categoryName":78,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000037","律师与法务",[80,81,82,83,84,85,86,87,88,89,90,28],"wechat search","wechat","search","capabilities","openclaw","design","web search","compliance","web","official","fetch",{"skillNo":92,"name":93,"nameZh":6,"description":94,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":95,"categories":96,"keywords":97,"publishedAt":44},"01M71ATNAVGZB35PFYM2GC5N00","trend-tap","Real-time trending topics aggregator across 7 platforms (X\u002FTwitter, Reddit, Google Trends, Hacker News, Zhihu, Bilibili, Weibo). Trigger: when user says 'trend', 'trends', 'trend tap', '热点', '热搜', or asks what is trending\u002Fhot. Do NOT use web_search — this skill already fetches live data from all platforms with zero API keys.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftrend-tap\u002FSKILL.md",[],[98,99,100,101,102,103,82,104,105,106,107,40,108,109,110,111,112,113,114,115],"trend","trend tap","tap","api keys","Bash","time","trending","hacker","aggregator","do","brew","live","data","google","install","read","across","api",{"skillNo":117,"name":118,"nameZh":6,"description":119,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":120,"categories":121,"keywords":122,"publishedAt":44},"01M71ATJ9AM5KM15AA8PS302EB","trend-radar","Real-time trending topics aggregator across 7 platforms (X\u002FTwitter, Reddit, Google Trends, Hacker News, Zhihu, Bilibili, Weibo). Trigger: when user says 'trend', 'trends', 'trend pulse', '热点', '热搜', or asks what is trending\u002Fhot. Do NOT use web_search — this skill already fetches live data from all platforms with zero API keys.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftrend-radar\u002FSKILL.md",[],[123,124,98,108,109,110,111,102,82,113,125,114,115,40,106,105,104,112,103,101],"trend radar","radar","pulse",{"skillNo":127,"name":128,"nameZh":6,"description":129,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":130,"categories":131,"keywords":132,"publishedAt":44},"01M71ATGF095N3EJM9G8SD0BB5","tech-news-daily","每日科技新闻汇——从全球多个 RSS 源抓取最新科技新闻，翻译（英→中）、去重、排版成每日简报。当用户询问科技新闻、科技新鲜事、每日科技、技术动态、Daily Tech News 或类似表达时触发此技能。","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftech-news-daily\u002FSKILL.md",[],[133,134,135,136,137,138],"news","tech","tech news daily","daily","rss","翻译",{"skillNo":140,"name":141,"nameZh":6,"description":142,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":143,"categories":144,"keywords":150,"publishedAt":44},"01M71ATFAEAMQ17M70NQNY7SR8","summarize","Summarize URLs or files with the summarize CLI (web, PDFs, images, audio, YouTube).","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fsummarize\u002FSKILL.md",[145],{"categoryNo":146,"categoryName":147,"taxonomyType":148,"taxonomyTypeDesc":149},"01JBSEEDCAT000000000000021","资料检索与研究","SCENARIO","使用场景",[141,88,151,152,153,28,108,154,155,156,100,157,112],"Audio","cli","youtube","images","https","files","pdfs",{"skillNo":159,"name":160,"nameZh":6,"description":161,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":162,"categories":163,"keywords":164,"publishedAt":44},"01M71ATDNS3R0M4H936PACQAWZ","sonoscli","Control Sonos speakers (discover\u002Fstatus\u002Fplay\u002Fvolume\u002Fgroup).","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fsonoscli\u002FSKILL.md",[],[160,165,166,167,112,168,155,169,170,171,172,173],"status","play","go","latest","github","discover","control","cmd","volume"]