bps-kit 1.2.2 → 1.3.1

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