Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,30 @@ Examples in parameter configuration:
- "Set value to ={{ $('Previous Node').item.json.value }}"
- "Set message to ={{ $('HTTP Request').item.json.message }}"`;

const EXPRESSION_TECHNIQUES = `Expressions support JavaScript methods

Regex operations:
- Test pattern: ={{ /pattern/.test($json.text) }}
- Extract match: ={{ $json.text.match(/pattern/)?.[1] }}
- Replace text: ={{ $json.text.replace(/pattern/, 'replacement') }}
- Split by pattern: ={{ $json.text.split(/pattern/) }}

String operations:
- Uppercase: ={{ $json.text.toUpperCase() }}
- Trim whitespace: ={{ $json.text.trim() }}
- Substring: ={{ $json.text.substring(0, 10) }}

Array operations:
- First item: ={{ $json.items[0] }}
- Filter: ={{ $json.items.filter(i => i.active) }}
- Map: ={{ $json.items.map(i => i.name) }}
- Join: ={{ $json.items.join(', ') }}

Generating items from expressions (use with Split Out node):
- Create array from comma string: ={{ $json.text.split(',') }}
- Generate range: ={{ Array.from({{length: 5}}, (_, i) => i + 1) }}
- Use with Split Out node to create multiple output items from a single input`;

const TOOL_NODE_EXPRESSIONS = `Tool nodes (types ending in "Tool") support $fromAI expressions:
- "Set sendTo to ={{ $fromAI('to') }}"
- "Set subject to ={{ $fromAI('subject') }}"
Expand Down Expand Up @@ -169,6 +193,7 @@ export function buildConfiguratorPrompt(): string {
.section('workflow_json_detection', WORKFLOW_JSON_DETECTION)
.section('parameter_configuration', PARAMETER_CONFIGURATION)
.section('data_referencing', DATA_REFERENCING)
.section('expression_techniques', EXPRESSION_TECHNIQUES)
.section('tool_node_expressions', TOOL_NODE_EXPRESSIONS)
.section('critical_parameters', CRITICAL_PARAMETERS)
.section('default_values_warning', DEFAULT_VALUES_WARNING)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,65 @@ const SUB_NODES_SEARCHES = `When searching for AI nodes, ALSO search for their r

const STRUCTURED_OUTPUT_PARSER = structuredOutputParser.usage;

const CODE_NODE_ALTERNATIVES = `CRITICAL: Prefer native n8n nodes over Code node. Code nodes are slower (sandboxed environment).

**Edit Fields (Set) with expressions is your go-to node for data manipulation:**
- Adding new fields with values or expressions
- Renaming or removing fields
- Mapping data from one structure to another
- Massaging/transforming field values using expressions
- Restructuring JSON objects
- Setting variables or constants
- Creating hardcoded values, lists and objects

**Native node alternatives - use INSTEAD of Code node:**

| Task | Use This |
|------|----------|
| Add/modify/rename fields | Edit Fields (Set) |
| Set hardcoded values/config/objects/lists | Edit Fields (Set) |
| Map/massage/transform data | Edit Fields (Set) |
| Generate list of items | Edit Fields (Set) + Split Out |
| Filter items by condition | Filter |
| Route by condition | If or Switch |
| Split array into items | Split Out |
| Combine multiple items | Aggregate |
| Merge data from branches | Merge |
| Summarize/pivot data | Summarize |
| Sort items | Sort |
| Remove duplicates | Remove Duplicates |
| Limit items | Limit |
| Format as HTML | HTML |
| Parse AI output | Structured Output Parser |
| Date/time operations | Date & Time |
| Compare datasets | Compare Datasets |
| Throw errors | Stop and Error |
| Regex pattern matching | If node with expression |
| Extract text with regex | Edit Fields (Set) with expression |
| Validate text format | If node with regex expression |
| Parse/extract fields from text | Edit Fields (Set) |

**Regex works in expressions - no Code node needed:**
- Test pattern
- Extract match
- Replace text
- Split by pattern

**Code node is ONLY appropriate for:**
- Complex multi-step algorithms that cannot be expressed in single expressions
- Operations requiring external libraries or complex data structures
- Mathematical calculations beyond simple expressions

**NEVER use Code node for:**
- Simple data transformations (use Edit Fields)
- Setting hardcoded values or configuration (use Edit Fields)
- Filtering/routing (use Filter, If, Switch)
- Array operations (use Split Out, Aggregate)
- Basic data restructuring (use Edit Fields + expressions)
- Regex operations (use expressions in If or Edit Fields nodes)
- Text extraction or parsing (use Edit Fields with expressions)
- Logging using console.log unless user explicitly asks - only useful for debugging, not production`;

const CRITICAL_RULES = `- NEVER ask clarifying questions
- ALWAYS call get_best_practices first
- THEN Call search_nodes to learn about available nodes and their inputs and outputs
Expand All @@ -227,7 +286,8 @@ const CRITICAL_RULES = `- NEVER ask clarifying questions
- ONLY flag connectionChangingParameters if they appear in <input> or <output> expressions
- If no parameters appear in connection expressions, return empty array []
- Output ONLY: nodesFound with {{ nodeName, version, reasoning, connectionChangingParameters }}
- When user specifies a model name (e.g., 'gpt-4.1-mini') try to use this if it is a valid option`;
- When user specifies a model name (e.g., 'gpt-4.1-mini') try to use this if it is a valid option
- PREFER native n8n nodes (especially Edit Fields) over Code node`;

const RESTRICTIONS = `- Output text commentary between tool calls
- Include bestPractices or categorization in submit_discovery_results
Expand Down Expand Up @@ -289,6 +349,7 @@ export function buildDiscoveryPrompt(options: DiscoveryPromptOptions): string {
.section('process', processSteps)
.section('technique_categorization', TECHNIQUE_CATEGORIZATION)
.section('technique_clarifications', TECHNIQUE_CLARIFICATIONS)
.section('code_node_alternatives', CODE_NODE_ALTERNATIVES)
.section('connection_changing_parameters', CONNECTION_PARAMETERS)
.section('dynamic_output_nodes', DYNAMIC_OUTPUT_NODES)
.section('sub_nodes_searches', SUB_NODES_SEARCHES)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,22 +69,6 @@ export class DataTransformationBestPractices implements BestPracticesDocument {

#### Code Node (n8n-nodes-base.code)

**Built-in Nodes vs. Code Node**
- Prefer basic built-in nodes (Edit Fields, Filter, Split Out, Summarize, Aggregate, etc.) over Code node. Use Code only for complex logic that can't be achieved otherwise.
- Rule of thumb: if the goal can be achieved with fewer than 5 basic nodes, use basic nodes

**When NOT to Use**: Code node may be slower than core nodes (like Edit Fields, If, Switch, Split Out, Aggregate, etc.) as Code nodes run in a sandboxed environment. Avoid the code node where possible — it should only be used for complex transformations that can't be done with other nodes. For example, DO NOT use it for:
- Adding or removing fields from items (use the 'edit fields' node instead)
- Single-line data transformations of item fields (use the 'edit fields' node instead)
- Filtering items based on their fields (use the 'filter' node instead)
- Pivoting or summarizing data across multiple items (use the 'summarize' node instead)
- Splitting arrays inside items out into multiple items (use the 'split out' node instead)
- Aggregating multiple items into a single item (use the 'aggregate' node instead)
- Sorting items in an array based on their fields (use the 'Sort' node instead)
- Generating HTML from text or formatting text as HTML (use the 'HTML' node set to operation 'Generate HTML Template' or 'Convert to HTML Table' instead)

**When to Use**: Complex transformations impossible with built-in nodes

**Execution Modes**:
- "Run Once per Item": Process each item independently
- "Run Once for All Items": Access entire dataset (for aggregation)
Expand Down
Loading