@awesomate/hosting-mcp 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/index.js +204 -8
  2. package/package.json +2 -2
  3. package/skill/awesomate-app-builder/SKILL.md +5 -1
  4. package/skill/awesomate-credentials/SKILL.md +1 -1
  5. package/skill/awesomate-hosting/SKILL.md +50 -159
  6. package/skill/awesomate-hosting/references/connect-troubleshooting.md +77 -0
  7. package/skill/awesomate-hosting/references/multi-account.md +33 -0
  8. package/skill/awesomate-hosting/references/rest-fallback.md +30 -0
  9. package/skill/awesomate-hosting/scripts/bootstrap.mjs +27 -7
  10. package/skill/awesomate-n8n/SKILL.md +153 -147
  11. package/skill/awesomate-n8n/evals/ai-agent-build/graders/grader.md +31 -0
  12. package/skill/awesomate-n8n/evals/ai-agent-build/prompt.md +1 -0
  13. package/skill/awesomate-n8n/evals/build-form-email/graders/grader.md +30 -0
  14. package/skill/awesomate-n8n/evals/build-form-email/prompt.md +1 -0
  15. package/skill/awesomate-n8n/evals/datatable-dedupe/graders/grader.md +32 -0
  16. package/skill/awesomate-n8n/evals/datatable-dedupe/prompt.md +2 -0
  17. package/skill/awesomate-n8n/evals/diagnose-failure/graders/grader.md +27 -0
  18. package/skill/awesomate-n8n/evals/diagnose-failure/prompt.md +2 -0
  19. package/skill/awesomate-n8n/evals/essentials-upsell/graders/grader.md +27 -0
  20. package/skill/awesomate-n8n/evals/essentials-upsell/prompt.md +2 -0
  21. package/skill/awesomate-n8n/evals/live-change-promote/graders/grader.md +35 -0
  22. package/skill/awesomate-n8n/evals/live-change-promote/prompt.md +2 -0
  23. package/skill/awesomate-n8n/evals/possibilities-grounded/graders/grader.md +28 -0
  24. package/skill/awesomate-n8n/evals/possibilities-grounded/prompt.md +1 -0
  25. package/skill/awesomate-n8n/evals/validated-not-done/graders/grader.md +27 -0
  26. package/skill/awesomate-n8n/evals/validated-not-done/prompt.md +2 -0
  27. package/skill/awesomate-n8n/evals/vars-not-env/graders/grader.md +26 -0
  28. package/skill/awesomate-n8n/evals/vars-not-env/prompt.md +2 -0
  29. package/skill/awesomate-n8n/evals/webhook-body-fix/graders/grader.md +26 -0
  30. package/skill/awesomate-n8n/evals/webhook-body-fix/prompt.md +3 -0
  31. package/skill/awesomate-n8n/references/ai-agents.md +135 -0
  32. package/skill/awesomate-n8n/references/datatables.md +105 -0
  33. package/skill/awesomate-n8n/references/{node-recipes.md → platform-notes.md} +56 -7
  34. package/skill/awesomate-n8n/references/possibilities.md +83 -0
  35. package/skill/awesomate-n8n/references/testing-policy.md +115 -0
  36. package/skill/awesomate-n8n/references/troubleshooting.md +69 -0
  37. package/skill/awesomate-n8n/references/upgrade-loop.md +98 -0
  38. package/skill/awesomate-n8n/references/vendor/MANIFEST.json +26 -0
  39. package/skill/awesomate-n8n/references/vendor/code-node/BUILTIN_FUNCTIONS.md +779 -0
  40. package/skill/awesomate-n8n/references/vendor/code-node/COMMON_PATTERNS.md +1123 -0
  41. package/skill/awesomate-n8n/references/vendor/code-node/DATA_ACCESS.md +797 -0
  42. package/skill/awesomate-n8n/references/vendor/code-node/ERROR_PATTERNS.md +776 -0
  43. package/skill/awesomate-n8n/references/vendor/code-node/SKILL.md +703 -0
  44. package/skill/awesomate-n8n/references/vendor/expressions/COMMON_MISTAKES.md +406 -0
  45. package/skill/awesomate-n8n/references/vendor/expressions/EXAMPLES.md +496 -0
  46. package/skill/awesomate-n8n/references/vendor/expressions/SKILL.md +525 -0
  47. package/skill/awesomate-n8n/references/vendor/node-configuration/DEPENDENCIES.md +743 -0
  48. package/skill/awesomate-n8n/references/vendor/node-configuration/OPERATION_PATTERNS.md +926 -0
  49. package/skill/awesomate-n8n/references/vendor/node-configuration/SKILL.md +583 -0
  50. package/skill/awesomate-n8n/references/vendor/validation/ERROR_CATALOG.md +781 -0
  51. package/skill/awesomate-n8n/references/vendor/validation/FALSE_POSITIVES.md +695 -0
  52. package/skill/awesomate-n8n/references/vendor/validation/SKILL.md +414 -0
  53. package/skill/awesomate-n8n/references/vendor/workflow-patterns/SKILL.md +413 -0
  54. package/skill/awesomate-n8n/references/vendor/workflow-patterns/ai_agent_workflow.md +797 -0
  55. package/skill/awesomate-n8n/references/vendor/workflow-patterns/database_operations.md +798 -0
  56. package/skill/awesomate-n8n/references/vendor/workflow-patterns/http_api_integration.md +747 -0
  57. package/skill/awesomate-n8n/references/vendor/workflow-patterns/scheduled_tasks.md +786 -0
  58. package/skill/awesomate-n8n/references/vendor/workflow-patterns/webhook_processing.md +558 -0
@@ -0,0 +1,776 @@
1
+ <!--
2
+ VENDORED from n8n-builder@d293559 (n8n-code-javascript/ERROR_PATTERNS.md) — DO NOT EDIT HERE.
3
+ Edit the source in ~/Projects/n8n-builder, then re-run:
4
+ node mcp/scripts/sync-n8n-references.mjs --write
5
+
6
+ Awesomate platform overrides — where this file conflicts with
7
+ ../platform-notes.md, platform-notes wins:
8
+ - $env is BLOCKED fleet-wide → use {{ $vars.key || 'fallback' }}
9
+ - Task runners are ON → no $helpers in Code nodes; use HTTP Request nodes
10
+ - Webhook payloads live at $json.body
11
+ - saveExecutionProgress must stay false
12
+ -->
13
+
14
+ # Error Patterns - JavaScript Code Node
15
+
16
+ Complete guide to avoiding the most common Code node errors.
17
+
18
+ ---
19
+
20
+ ## Overview
21
+
22
+ This guide covers the **top 5 error patterns** encountered in n8n Code nodes. Understanding and avoiding these errors will save you significant debugging time.
23
+
24
+ **Error Frequency**:
25
+ 1. Empty Code / Missing Return - **38% of failures**
26
+ 2. Expression Syntax Confusion - **8% of failures**
27
+ 3. Incorrect Return Wrapper - **5% of failures**
28
+ 4. Unmatched Expression Brackets - **6% of failures**
29
+ 5. Missing Null Checks - **Common runtime error**
30
+
31
+ ---
32
+
33
+ ## Error #1: Empty Code or Missing Return Statement
34
+
35
+ **Frequency**: Most common error (38% of all validation failures)
36
+
37
+ **What Happens**:
38
+ - Workflow execution fails
39
+ - Next nodes receive no data
40
+ - Error: "Code cannot be empty" or "Code must return data"
41
+
42
+ ### The Problem
43
+
44
+ ```javascript
45
+ // ❌ ERROR: No code at all
46
+ // (Empty code field)
47
+ ```
48
+
49
+ ```javascript
50
+ // ❌ ERROR: Code executes but doesn't return anything
51
+ const items = $input.all();
52
+
53
+ // Process items
54
+ for (const item of items) {
55
+ console.log(item.json.name);
56
+ }
57
+
58
+ // Forgot to return!
59
+ ```
60
+
61
+ ```javascript
62
+ // ❌ ERROR: Early return path exists, but not all paths return
63
+ const items = $input.all();
64
+
65
+ if (items.length === 0) {
66
+ return []; // ✅ This path returns
67
+ }
68
+
69
+ // Process items
70
+ const processed = items.map(item => ({json: item.json}));
71
+
72
+ // ❌ Forgot to return processed!
73
+ ```
74
+
75
+ ### The Solution
76
+
77
+ ```javascript
78
+ // ✅ CORRECT: Always return data
79
+ const items = $input.all();
80
+
81
+ // Process items
82
+ const processed = items.map(item => ({
83
+ json: {
84
+ ...item.json,
85
+ processed: true
86
+ }
87
+ }));
88
+
89
+ return processed; // ✅ Return statement present
90
+ ```
91
+
92
+ ```javascript
93
+ // ✅ CORRECT: Return empty array if no items
94
+ const items = $input.all();
95
+
96
+ if (items.length === 0) {
97
+ return []; // Valid: empty array when no data
98
+ }
99
+
100
+ // Process and return
101
+ return items.map(item => ({json: item.json}));
102
+ ```
103
+
104
+ ```javascript
105
+ // ✅ CORRECT: All code paths return
106
+ const items = $input.all();
107
+
108
+ if (items.length === 0) {
109
+ return [];
110
+ } else if (items.length === 1) {
111
+ return [{json: {single: true, data: items[0].json}}];
112
+ } else {
113
+ return items.map(item => ({json: item.json}));
114
+ }
115
+
116
+ // All paths covered
117
+ ```
118
+
119
+ ### Checklist
120
+
121
+ - [ ] Code field is not empty
122
+ - [ ] Return statement exists
123
+ - [ ] ALL code paths return data (if/else branches)
124
+ - [ ] Return format is correct (`[{json: {...}}]`)
125
+ - [ ] Return happens even on errors (use try-catch)
126
+
127
+ ---
128
+
129
+ ## Error #2: Expression Syntax Confusion
130
+
131
+ **Frequency**: 8% of validation failures
132
+
133
+ **What Happens**:
134
+ - Syntax error in code execution
135
+ - Error: "Unexpected token" or "Expression syntax is not valid in Code nodes"
136
+ - Template variables not evaluated
137
+
138
+ ### The Problem
139
+
140
+ n8n has TWO distinct syntaxes:
141
+ 1. **Expression syntax** `{{ }}` - Used in OTHER nodes (Set, IF, HTTP Request)
142
+ 2. **JavaScript** - Used in CODE nodes (no `{{ }}`)
143
+
144
+ Many developers mistakenly use expression syntax inside Code nodes.
145
+
146
+ ```javascript
147
+ // ❌ WRONG: Using n8n expression syntax in Code node
148
+ const userName = "{{ $json.name }}";
149
+ const userEmail = "{{ $json.body.email }}";
150
+
151
+ return [{
152
+ json: {
153
+ name: userName,
154
+ email: userEmail
155
+ }
156
+ }];
157
+
158
+ // Result: Literal string "{{ $json.name }}", NOT the value!
159
+ ```
160
+
161
+ ```javascript
162
+ // ❌ WRONG: Trying to evaluate expressions
163
+ const value = "{{ $now.toFormat('yyyy-MM-dd') }}";
164
+ ```
165
+
166
+ ### The Solution
167
+
168
+ ```javascript
169
+ // ✅ CORRECT: Use JavaScript directly (no {{ }})
170
+ const userName = $json.name;
171
+ const userEmail = $json.body.email;
172
+
173
+ return [{
174
+ json: {
175
+ name: userName,
176
+ email: userEmail
177
+ }
178
+ }];
179
+ ```
180
+
181
+ ```javascript
182
+ // ✅ CORRECT: JavaScript template literals (use backticks)
183
+ const message = `Hello, ${$json.name}! Your email is ${$json.email}`;
184
+
185
+ return [{
186
+ json: {
187
+ greeting: message
188
+ }
189
+ }];
190
+ ```
191
+
192
+ ```javascript
193
+ // ✅ CORRECT: Direct variable access
194
+ const item = $input.first().json;
195
+
196
+ return [{
197
+ json: {
198
+ name: item.name,
199
+ email: item.email,
200
+ timestamp: new Date().toISOString() // JavaScript Date, not {{ }}
201
+ }
202
+ }];
203
+ ```
204
+
205
+ ### Comparison Table
206
+
207
+ | Context | Syntax | Example |
208
+ |---------|--------|---------|
209
+ | Set node | `{{ }}` expressions | `{{ $json.name }}` |
210
+ | IF node | `{{ }}` expressions | `{{ $json.age > 18 }}` |
211
+ | HTTP Request URL | `{{ }}` expressions | `{{ $json.userId }}` |
212
+ | **Code node** | **JavaScript** | `$json.name` |
213
+ | **Code node strings** | **Template literals** | `` `Hello ${$json.name}` `` |
214
+
215
+ ### Quick Fix Guide
216
+
217
+ ```javascript
218
+ // WRONG → RIGHT conversions
219
+
220
+ // ❌ "{{ $json.field }}"
221
+ // ✅ $json.field
222
+
223
+ // ❌ "{{ $now }}"
224
+ // ✅ new Date().toISOString()
225
+
226
+ // ❌ "{{ $node['HTTP Request'].json.data }}"
227
+ // ✅ $node["HTTP Request"].json.data
228
+
229
+ // ❌ `{{ $json.firstName }} {{ $json.lastName }}`
230
+ // ✅ `${$json.firstName} ${$json.lastName}`
231
+ ```
232
+
233
+ ---
234
+
235
+ ## Error #3: Incorrect Return Wrapper Format
236
+
237
+ **Frequency**: 5% of validation failures
238
+
239
+ **What Happens**:
240
+ - Error: "Return value must be an array of objects"
241
+ - Error: "Each item must have a json property"
242
+ - Next nodes receive malformed data
243
+
244
+ ### The Problem
245
+
246
+ Code nodes MUST return:
247
+ - **Array** of objects
248
+ - Each object MUST have a **`json` property**
249
+
250
+ ```javascript
251
+ // ❌ WRONG: Returning object instead of array
252
+ return {
253
+ json: {
254
+ result: 'success'
255
+ }
256
+ };
257
+ // Missing array wrapper []
258
+ ```
259
+
260
+ ```javascript
261
+ // ❌ WRONG: Returning array without json wrapper
262
+ return [
263
+ {id: 1, name: 'Alice'},
264
+ {id: 2, name: 'Bob'}
265
+ ];
266
+ // Missing json property
267
+ ```
268
+
269
+ ```javascript
270
+ // ❌ WRONG: Returning plain value
271
+ return "processed";
272
+ ```
273
+
274
+ ```javascript
275
+ // ❌ WRONG: Returning items without mapping
276
+ return $input.all();
277
+ // Works if items already have json property, but not guaranteed
278
+ ```
279
+
280
+ ```javascript
281
+ // ❌ WRONG: Incomplete structure
282
+ return [{data: {result: 'success'}}];
283
+ // Should be {json: {...}}, not {data: {...}}
284
+ ```
285
+
286
+ ### The Solution
287
+
288
+ ```javascript
289
+ // ✅ CORRECT: Single result
290
+ return [{
291
+ json: {
292
+ result: 'success',
293
+ timestamp: new Date().toISOString()
294
+ }
295
+ }];
296
+ ```
297
+
298
+ ```javascript
299
+ // ✅ CORRECT: Multiple results
300
+ return [
301
+ {json: {id: 1, name: 'Alice'}},
302
+ {json: {id: 2, name: 'Bob'}},
303
+ {json: {id: 3, name: 'Carol'}}
304
+ ];
305
+ ```
306
+
307
+ ```javascript
308
+ // ✅ CORRECT: Transforming array
309
+ const items = $input.all();
310
+
311
+ return items.map(item => ({
312
+ json: {
313
+ id: item.json.id,
314
+ name: item.json.name,
315
+ processed: true
316
+ }
317
+ }));
318
+ ```
319
+
320
+ ```javascript
321
+ // ✅ CORRECT: Empty result
322
+ return [];
323
+ // Valid when no data to return
324
+ ```
325
+
326
+ ```javascript
327
+ // ✅ CORRECT: Conditional returns
328
+ if (shouldProcess) {
329
+ return [{json: {result: 'processed'}}];
330
+ } else {
331
+ return [];
332
+ }
333
+ ```
334
+
335
+ ### Return Format Checklist
336
+
337
+ - [ ] Return value is an **array** `[...]`
338
+ - [ ] Each array element has **`json` property**
339
+ - [ ] Structure is `[{json: {...}}]` or `[{json: {...}}, {json: {...}}]`
340
+ - [ ] NOT `{json: {...}}` (missing array wrapper)
341
+ - [ ] NOT `[{...}]` (missing json property)
342
+
343
+ ### Common Scenarios
344
+
345
+ ```javascript
346
+ // Scenario 1: Single object from API
347
+ const response = $input.first().json;
348
+
349
+ // ✅ CORRECT
350
+ return [{json: response}];
351
+
352
+ // ❌ WRONG
353
+ return {json: response};
354
+
355
+
356
+ // Scenario 2: Array of objects
357
+ const users = $input.all();
358
+
359
+ // ✅ CORRECT
360
+ return users.map(user => ({json: user.json}));
361
+
362
+ // ❌ WRONG
363
+ return users; // Risky - depends on existing structure
364
+
365
+
366
+ // Scenario 3: Computed result
367
+ const total = $input.all().reduce((sum, item) => sum + item.json.amount, 0);
368
+
369
+ // ✅ CORRECT
370
+ return [{json: {total}}];
371
+
372
+ // ❌ WRONG
373
+ return {total};
374
+
375
+
376
+ // Scenario 4: No results
377
+ // ✅ CORRECT
378
+ return [];
379
+
380
+ // ❌ WRONG
381
+ return null;
382
+ ```
383
+
384
+ ---
385
+
386
+ ## Error #4: Unmatched Expression Brackets
387
+
388
+ **Frequency**: 6% of validation failures
389
+
390
+ **What Happens**:
391
+ - Parsing error during save
392
+ - Error: "Unmatched expression brackets"
393
+ - Code appears correct but fails validation
394
+
395
+ ### The Problem
396
+
397
+ This error typically occurs when:
398
+ 1. Strings contain unbalanced quotes
399
+ 2. Multi-line strings with special characters
400
+ 3. Template literals with nested brackets
401
+
402
+ ```javascript
403
+ // ❌ WRONG: Unescaped quote in string
404
+ const message = "It's a nice day";
405
+ // Single quote breaks string
406
+ ```
407
+
408
+ ```javascript
409
+ // ❌ WRONG: Unbalanced brackets in regex
410
+ const pattern = /\{(\w+)\}/; // JSON storage issue
411
+ ```
412
+
413
+ ```javascript
414
+ // ❌ WRONG: Multi-line string with quotes
415
+ const html = "
416
+ <div class="container">
417
+ <p>Hello</p>
418
+ </div>
419
+ ";
420
+ // Quote balance issues
421
+ ```
422
+
423
+ ### The Solution
424
+
425
+ ```javascript
426
+ // ✅ CORRECT: Escape quotes
427
+ const message = "It\\'s a nice day";
428
+ // Or use different quotes
429
+ const message = "It's a nice day"; // Double quotes work
430
+ ```
431
+
432
+ ```javascript
433
+ // ✅ CORRECT: Escape regex properly
434
+ const pattern = /\\{(\\w+)\\}/;
435
+ ```
436
+
437
+ ```javascript
438
+ // ✅ CORRECT: Template literals for multi-line
439
+ const html = `
440
+ <div class="container">
441
+ <p>Hello</p>
442
+ </div>
443
+ `;
444
+ // Backticks handle multi-line and quotes
445
+ ```
446
+
447
+ ```javascript
448
+ // ✅ CORRECT: Escape backslashes
449
+ const path = "C:\\\\Users\\\\Documents\\\\file.txt";
450
+ ```
451
+
452
+ ### Escaping Guide
453
+
454
+ | Character | Escape As | Example |
455
+ |-----------|-----------|---------|
456
+ | Single quote in single-quoted string | `\\'` | `'It\\'s working'` |
457
+ | Double quote in double-quoted string | `\\"` | `"She said \\"hello\\""` |
458
+ | Backslash | `\\\\` | `"C:\\\\path"` |
459
+ | Newline | `\\n` | `"Line 1\\nLine 2"` |
460
+ | Tab | `\\t` | `"Column1\\tColumn2"` |
461
+
462
+ ### Best Practices
463
+
464
+ ```javascript
465
+ // ✅ BEST: Use template literals for complex strings
466
+ const message = `User ${name} said: "Hello!"`;
467
+
468
+ // ✅ BEST: Use template literals for HTML
469
+ const html = `
470
+ <div class="${className}">
471
+ <h1>${title}</h1>
472
+ <p>${content}</p>
473
+ </div>
474
+ `;
475
+
476
+ // ✅ BEST: Use template literals for JSON
477
+ const jsonString = `{
478
+ "name": "${name}",
479
+ "email": "${email}"
480
+ }`;
481
+ ```
482
+
483
+ ---
484
+
485
+ ## Error #5: Missing Null Checks / Undefined Access
486
+
487
+ **Frequency**: Very common runtime error
488
+
489
+ **What Happens**:
490
+ - Workflow execution stops
491
+ - Error: "Cannot read property 'X' of undefined"
492
+ - Error: "Cannot read property 'X' of null"
493
+ - Crashes on missing data
494
+
495
+ ### The Problem
496
+
497
+ ```javascript
498
+ // ❌ WRONG: No null check - crashes if user doesn't exist
499
+ const email = item.json.user.email;
500
+ ```
501
+
502
+ ```javascript
503
+ // ❌ WRONG: Assumes array has items
504
+ const firstItem = $input.all()[0].json;
505
+ ```
506
+
507
+ ```javascript
508
+ // ❌ WRONG: Assumes nested property exists
509
+ const city = $json.address.city;
510
+ ```
511
+
512
+ ```javascript
513
+ // ❌ WRONG: No validation before array operations
514
+ const names = $json.users.map(user => user.name);
515
+ ```
516
+
517
+ ### The Solution
518
+
519
+ ```javascript
520
+ // ✅ CORRECT: Optional chaining
521
+ const email = item.json?.user?.email || 'no-email@example.com';
522
+ ```
523
+
524
+ ```javascript
525
+ // ✅ CORRECT: Check array length
526
+ const items = $input.all();
527
+
528
+ if (items.length === 0) {
529
+ return [];
530
+ }
531
+
532
+ const firstItem = items[0].json;
533
+ ```
534
+
535
+ ```javascript
536
+ // ✅ CORRECT: Guard clauses
537
+ const data = $input.first().json;
538
+
539
+ if (!data.address) {
540
+ return [{json: {error: 'No address provided'}}];
541
+ }
542
+
543
+ const city = data.address.city;
544
+ ```
545
+
546
+ ```javascript
547
+ // ✅ CORRECT: Default values
548
+ const users = $json.users || [];
549
+ const names = users.map(user => user.name || 'Unknown');
550
+ ```
551
+
552
+ ```javascript
553
+ // ✅ CORRECT: Try-catch for risky operations
554
+ try {
555
+ const email = item.json.user.email.toLowerCase();
556
+ return [{json: {email}}];
557
+ } catch (error) {
558
+ return [{
559
+ json: {
560
+ error: 'Invalid user data',
561
+ details: error.message
562
+ }
563
+ }];
564
+ }
565
+ ```
566
+
567
+ ### Safe Access Patterns
568
+
569
+ ```javascript
570
+ // Pattern 1: Optional chaining (modern, recommended)
571
+ const value = data?.nested?.property?.value;
572
+
573
+ // Pattern 2: Logical OR with default
574
+ const value = data.property || 'default';
575
+
576
+ // Pattern 3: Ternary check
577
+ const value = data.property ? data.property : 'default';
578
+
579
+ // Pattern 4: Guard clause
580
+ if (!data.property) {
581
+ return [];
582
+ }
583
+ const value = data.property;
584
+
585
+ // Pattern 5: Try-catch
586
+ try {
587
+ const value = data.nested.property.value;
588
+ } catch (error) {
589
+ const value = 'default';
590
+ }
591
+ ```
592
+
593
+ ### Webhook Data Safety
594
+
595
+ ```javascript
596
+ // Webhook data requires extra safety
597
+
598
+ // ❌ RISKY: Assumes all fields exist
599
+ const name = $json.body.user.name;
600
+ const email = $json.body.user.email;
601
+
602
+ // ✅ SAFE: Check each level
603
+ const body = $json.body || {};
604
+ const user = body.user || {};
605
+ const name = user.name || 'Unknown';
606
+ const email = user.email || 'no-email';
607
+
608
+ // ✅ BETTER: Optional chaining
609
+ const name = $json.body?.user?.name || 'Unknown';
610
+ const email = $json.body?.user?.email || 'no-email';
611
+ ```
612
+
613
+ ### Array Safety
614
+
615
+ ```javascript
616
+ // ❌ RISKY: No length check
617
+ const items = $input.all();
618
+ const firstId = items[0].json.id;
619
+
620
+ // ✅ SAFE: Check length
621
+ const items = $input.all();
622
+
623
+ if (items.length > 0) {
624
+ const firstId = items[0].json.id;
625
+ } else {
626
+ // Handle empty case
627
+ return [];
628
+ }
629
+
630
+ // ✅ BETTER: Use $input.first()
631
+ const firstItem = $input.first();
632
+ const firstId = firstItem.json.id; // Built-in safety
633
+ ```
634
+
635
+ ### Object Property Safety
636
+
637
+ ```javascript
638
+ // ❌ RISKY: Direct access
639
+ const config = $json.settings.advanced.timeout;
640
+
641
+ // ✅ SAFE: Step by step with defaults
642
+ const settings = $json.settings || {};
643
+ const advanced = settings.advanced || {};
644
+ const timeout = advanced.timeout || 30000;
645
+
646
+ // ✅ BETTER: Optional chaining
647
+ const timeout = $json.settings?.advanced?.timeout ?? 30000;
648
+ // Note: ?? (nullish coalescing) vs || (logical OR)
649
+ ```
650
+
651
+ ---
652
+
653
+ ## Error Prevention Checklist
654
+
655
+ Use this checklist before deploying Code nodes:
656
+
657
+ ### Code Structure
658
+ - [ ] Code field is not empty
659
+ - [ ] Return statement exists
660
+ - [ ] All code paths return data
661
+
662
+ ### Return Format
663
+ - [ ] Returns array: `[...]`
664
+ - [ ] Each item has `json` property: `{json: {...}}`
665
+ - [ ] Format is `[{json: {...}}]`
666
+
667
+ ### Syntax
668
+ - [ ] No `{{ }}` expression syntax (use JavaScript)
669
+ - [ ] Template literals use backticks: `` `${variable}` ``
670
+ - [ ] All quotes and brackets balanced
671
+ - [ ] Strings properly escaped
672
+
673
+ ### Data Safety
674
+ - [ ] Null checks for optional properties
675
+ - [ ] Array length checks before access
676
+ - [ ] Webhook data accessed via `.body`
677
+ - [ ] Try-catch for risky operations
678
+ - [ ] Default values for missing data
679
+
680
+ ### Testing
681
+ - [ ] Test with empty input
682
+ - [ ] Test with missing fields
683
+ - [ ] Test with unexpected data types
684
+ - [ ] Check browser console for errors
685
+
686
+ ---
687
+
688
+ ## Quick Error Reference
689
+
690
+ | Error Message | Likely Cause | Fix |
691
+ |---------------|--------------|-----|
692
+ | "Code cannot be empty" | Empty code field | Add meaningful code |
693
+ | "Code must return data" | Missing return statement | Add `return [...]` |
694
+ | "Return value must be an array" | Returning object instead of array | Wrap in `[...]` |
695
+ | "Each item must have json property" | Missing `json` wrapper | Use `{json: {...}}` |
696
+ | "Unexpected token" | Expression syntax `{{ }}` in code | Remove `{{ }}`, use JavaScript |
697
+ | "Cannot read property X of undefined" | Missing null check | Use optional chaining `?.` |
698
+ | "Cannot read property X of null" | Null value access | Add guard clause or default |
699
+ | "Unmatched expression brackets" | Quote/bracket imbalance | Check string escaping |
700
+
701
+ ---
702
+
703
+ ## Debugging Tips
704
+
705
+ ### 1. Use console.log()
706
+
707
+ ```javascript
708
+ const items = $input.all();
709
+ console.log('Items count:', items.length);
710
+ console.log('First item:', items[0]);
711
+
712
+ // Check browser console (F12) for output
713
+ ```
714
+
715
+ ### 2. Return Intermediate Results
716
+
717
+ ```javascript
718
+ // Debug by returning current state
719
+ const items = $input.all();
720
+ const processed = items.map(item => ({json: item.json}));
721
+
722
+ // Return to see what you have
723
+ return processed;
724
+ ```
725
+
726
+ ### 3. Try-Catch for Troubleshooting
727
+
728
+ ```javascript
729
+ try {
730
+ // Your code here
731
+ const result = riskyOperation();
732
+ return [{json: {result}}];
733
+ } catch (error) {
734
+ // See what failed
735
+ return [{
736
+ json: {
737
+ error: error.message,
738
+ stack: error.stack
739
+ }
740
+ }];
741
+ }
742
+ ```
743
+
744
+ ### 4. Validate Input Structure
745
+
746
+ ```javascript
747
+ const items = $input.all();
748
+
749
+ // Check what you received
750
+ console.log('Input structure:', JSON.stringify(items[0], null, 2));
751
+
752
+ // Then process
753
+ ```
754
+
755
+ ---
756
+
757
+ ## Summary
758
+
759
+ **Top 5 Errors to Avoid**:
760
+ 1. **Empty code / missing return** (38%) - Always return data
761
+ 2. **Expression syntax `{{ }}`** (8%) - Use JavaScript, not expressions
762
+ 3. **Wrong return format** (5%) - Always `[{json: {...}}]`
763
+ 4. **Unmatched brackets** (6%) - Escape strings properly
764
+ 5. **Missing null checks** - Use optional chaining `?.`
765
+
766
+ **Quick Prevention**:
767
+ - Return `[{json: {...}}]` format
768
+ - Use JavaScript, NOT `{{ }}` expressions
769
+ - Check for null/undefined before accessing
770
+ - Test with empty and invalid data
771
+ - Use browser console for debugging
772
+
773
+ **See Also**:
774
+ - [SKILL.md](SKILL.md) - Overview and best practices
775
+ - [DATA_ACCESS.md](DATA_ACCESS.md) - Safe data access patterns
776
+ - [COMMON_PATTERNS.md](COMMON_PATTERNS.md) - Working examples