From 892c4ed70a40c22c74155fe3625257a6e4988221 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romuald=20Cz=C5=82onkowski?= <56956555+czlonkowski@users.noreply.github.com> Date: Sun, 26 Oct 2025 11:07:30 +0100 Subject: [PATCH] Resolve GitHub Issue 292 in n8n-mcp (#375) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: add comprehensive documentation for removing node properties with undefined Add detailed documentation section for property removal pattern in n8n_update_partial_workflow tool: - New "Removing Properties with undefined" section explaining the pattern - Examples showing basic, nested, and batch property removal - Migration guide for deprecated properties (continueOnFail → onError) - Best practices for when to use undefined - Pitfalls to avoid (null vs undefined, mutual exclusivity, etc.) This addresses the documentation gap reported in issue #292 where users were confused about how to remove properties during node updates. Conceived by Romuald Członkowski - https://www.aiadvisors.pl/en 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude * fix: correct array property removal documentation in n8n_update_partial_workflow (Issue #292) Fixed critical documentation error showing array index notation [0] which doesn't work. The setNestedProperty implementation treats "headers[0]" as a literal object key, not an array index. Changes: - Updated nested property removal section to show entire array removal - Corrected example rm5 to use "parameters.headers" instead of "parameters.headers[0]" - Replaced misleading pitfall with accurate warning about array index notation not being supported Impact: - Prevents user confusion and non-functional code - All examples now show correct, working patterns - Clear warning helps users avoid this mistake Conceived by Romuald Członkowski - https://www.aiadvisors.pl/en 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --------- Co-authored-by: Claude --- CHANGELOG.md | 89 ++++++++++++ data/nodes.db | Bin 62623744 -> 62623744 bytes package.json | 2 +- package.runtime.json | 2 +- .../n8n-update-partial-workflow.ts | 131 +++++++++++++++++- 5 files changed, 218 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9bcd99..7e69518 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,95 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [2.22.7] - 2025-10-26 + +### 📝 Documentation Fixes + +**Issue #292: Corrected Array Property Removal Documentation in n8n_update_partial_workflow** + +Fixed critical documentation error in property removal patterns that could have led users to write non-functional code. + +#### Problem + +The documentation incorrectly showed using array index notation `[0]` for removing array elements: +```javascript +// INCORRECT (doesn't work as shown) +updates: { "parameters.headers[0]": undefined } +``` + +**Root Cause**: The `setNestedProperty` implementation doesn't parse array index notation like `[0]`. It treats `headers[0]` as a literal object key, not an array index. + +**Impact**: Users following the documentation would write code that doesn't behave as expected. The property `headers[0]` would be treated as an object key, not an array element reference. + +#### Fixed + +**Three documentation corrections in `src/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.ts`:** + +1. **Nested Property Removal Section** (lines 236-244): + - Changed comment from `// Remove array element` to `// Remove entire array property` + - Changed code from `"parameters.headers[0]": undefined` to `"parameters.headers": undefined` + +2. **Example rm5** (line 340): + - Changed comment from `// Remove array element` to `// Remove entire array property` + - Changed code from `"parameters.headers[0]": undefined` to `"parameters.headers": undefined` + +3. **Pitfalls Section** (line 405): + - OLD: `'Array element removal with undefined removes the element at that index, which may shift subsequent indices'` + - NEW: `'Array index notation (e.g., "parameters.headers[0]") is not supported - remove the entire array property instead'` + +#### Correct Usage + +**To remove an array property:** +```javascript +// Correct: Remove entire array +n8n_update_partial_workflow({ + id: "wf_012", + operations: [{ + type: "updateNode", + nodeName: "HTTP Request", + updates: { "parameters.headers": undefined } // Remove entire headers array + }] +}); +``` + +**NOT:** +```javascript +// Incorrect: Array index notation doesn't work +updates: { "parameters.headers[0]": undefined } // Treated as object key "headers[0]" +``` + +#### Impact + +- **Prevents User Confusion**: Clear documentation on what works vs. what doesn't +- **Accurate Examples**: All examples now show correct, working patterns +- **Better Error Prevention**: Pitfall warning helps users avoid this mistake +- **No Code Changes**: This is purely a documentation fix - no implementation changes needed + +#### Testing + +- ✅ Documentation reviewed by code-reviewer agent +- ✅ Tested by n8n-mcp-tester agent +- ✅ All examples verified against actual implementation behavior +- ✅ Pitfall accurately describes technical limitation + +#### Files Changed + +**Documentation (1 file)**: +- `src/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.ts` - Corrected 3 instances of array property removal documentation + +**Configuration (2 files)**: +- `package.json` - Version bump to 2.22.7 +- `package.runtime.json` - Version bump to 2.22.7 + +#### Related + +- **Issue**: #292 - Missing documentation on how to remove node properties using `updateNode` +- **PR**: #375 - Resolve GitHub Issue 292 in n8n-mcp +- **Code Review**: Identified critical array index notation documentation error +- **Root Cause**: Implementation doesn't parse array bracket notation `[N]` + +Conceived by Romuald Członkowski - [www.aiadvisors.pl/en](https://www.aiadvisors.pl/en) + ## [2.22.6] - 2025-10-25 ### 🐛 Bug Fixes diff --git a/data/nodes.db b/data/nodes.db index e22fcad531e550c45c3bfbd4698081589a9dca7e..72aae6d107c59ad303432da85b6b4b12f9b214eb 100644 GIT binary patch delta 78130 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 C(g~aZ diff --git a/package.json b/package.json index a4966da..2bd3af7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "n8n-mcp", - "version": "2.22.6", + "version": "2.22.7", "description": "Integration between n8n workflow automation and Model Context Protocol (MCP)", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/package.runtime.json b/package.runtime.json index 7c3334f..a56ffbf 100644 --- a/package.runtime.json +++ b/package.runtime.json @@ -1,6 +1,6 @@ { "name": "n8n-mcp-runtime", - "version": "2.22.5", + "version": "2.22.7", "description": "n8n MCP Server Runtime Dependencies Only", "private": true, "dependencies": { diff --git a/src/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.ts b/src/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.ts index c9822a0..0dc9835 100644 --- a/src/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.ts +++ b/src/mcp/tool-docs/workflow_management/n8n-update-partial-workflow.ts @@ -186,7 +186,115 @@ Please choose a different name. - Simply rename nodes with updateNode - no manual connection operations needed - Multiple renames in one call work atomically - Can rename a node and add/remove connections using the new name in the same batch -- Use \`validateOnly: true\` to preview effects before applying`, +- Use \`validateOnly: true\` to preview effects before applying + +## Removing Properties with undefined + +To remove a property from a node, set its value to \`undefined\` in the updates object. This is essential when migrating from deprecated properties or cleaning up optional configuration fields. + +### Why Use undefined? +- **Property removal vs. null**: Setting a property to \`undefined\` removes it completely from the node object, while \`null\` sets the property to a null value +- **Validation constraints**: Some properties are mutually exclusive (e.g., \`continueOnFail\` and \`onError\`). Simply setting one without removing the other will fail validation +- **Deprecated property migration**: When n8n deprecates properties, you must remove the old property before the new one will work + +### Basic Property Removal +\`\`\`javascript +// Remove error handling configuration +n8n_update_partial_workflow({ + id: "wf_123", + operations: [{ + type: "updateNode", + nodeName: "HTTP Request", + updates: { onError: undefined } + }] +}); + +// Remove disabled flag +n8n_update_partial_workflow({ + id: "wf_456", + operations: [{ + type: "updateNode", + nodeId: "node_abc", + updates: { disabled: undefined } + }] +}); +\`\`\` + +### Nested Property Removal +Use dot notation to remove nested properties: +\`\`\`javascript +// Remove nested parameter +n8n_update_partial_workflow({ + id: "wf_789", + operations: [{ + type: "updateNode", + nodeName: "API Request", + updates: { "parameters.authentication": undefined } + }] +}); + +// Remove entire array property +n8n_update_partial_workflow({ + id: "wf_012", + operations: [{ + type: "updateNode", + nodeName: "HTTP Request", + updates: { "parameters.headers": undefined } + }] +}); +\`\`\` + +### Migrating from Deprecated Properties +Common scenario: replacing \`continueOnFail\` with \`onError\`: +\`\`\`javascript +// WRONG: Setting only the new property leaves the old one +n8n_update_partial_workflow({ + id: "wf_123", + operations: [{ + type: "updateNode", + nodeName: "HTTP Request", + updates: { onError: "continueErrorOutput" } + }] +}); +// Error: continueOnFail and onError are mutually exclusive + +// CORRECT: Remove the old property first +n8n_update_partial_workflow({ + id: "wf_123", + operations: [{ + type: "updateNode", + nodeName: "HTTP Request", + updates: { + continueOnFail: undefined, + onError: "continueErrorOutput" + } + }] +}); +\`\`\` + +### Batch Property Removal +Remove multiple properties in one operation: +\`\`\`javascript +n8n_update_partial_workflow({ + id: "wf_345", + operations: [{ + type: "updateNode", + nodeName: "Data Processor", + updates: { + continueOnFail: undefined, + alwaysOutputData: undefined, + "parameters.legacy_option": undefined + } + }] +}); +\`\`\` + +### When to Use undefined +- Removing deprecated properties during migration +- Cleaning up optional configuration flags +- Resolving mutual exclusivity validation errors +- Removing stale or unnecessary node metadata +- Simplifying node configuration`, parameters: { id: { type: 'string', required: true, description: 'Workflow ID to update' }, operations: { @@ -223,7 +331,13 @@ Please choose a different name. '// Vector Store setup: Connect embeddings and documents\nn8n_update_partial_workflow({id: "ai7", operations: [\n {type: "addConnection", source: "Embeddings OpenAI", target: "Pinecone Vector Store", sourceOutput: "ai_embedding"},\n {type: "addConnection", source: "Default Data Loader", target: "Pinecone Vector Store", sourceOutput: "ai_document"}\n]})', '// Connect Vector Store Tool to AI Agent (retrieval setup)\nn8n_update_partial_workflow({id: "ai8", operations: [\n {type: "addConnection", source: "Pinecone Vector Store", target: "Vector Store Tool", sourceOutput: "ai_vectorStore"},\n {type: "addConnection", source: "Vector Store Tool", target: "AI Agent", sourceOutput: "ai_tool"}\n]})', '// Rewire AI Agent to use different language model\nn8n_update_partial_workflow({id: "ai9", operations: [{type: "rewireConnection", source: "AI Agent", from: "OpenAI Chat Model", to: "Anthropic Chat Model", sourceOutput: "ai_languageModel"}]})', - '// Replace all AI tools for an agent\nn8n_update_partial_workflow({id: "ai10", operations: [\n {type: "removeConnection", source: "Old Tool 1", target: "AI Agent", sourceOutput: "ai_tool"},\n {type: "removeConnection", source: "Old Tool 2", target: "AI Agent", sourceOutput: "ai_tool"},\n {type: "addConnection", source: "New HTTP Tool", target: "AI Agent", sourceOutput: "ai_tool"},\n {type: "addConnection", source: "New Code Tool", target: "AI Agent", sourceOutput: "ai_tool"}\n]})' + '// Replace all AI tools for an agent\nn8n_update_partial_workflow({id: "ai10", operations: [\n {type: "removeConnection", source: "Old Tool 1", target: "AI Agent", sourceOutput: "ai_tool"},\n {type: "removeConnection", source: "Old Tool 2", target: "AI Agent", sourceOutput: "ai_tool"},\n {type: "addConnection", source: "New HTTP Tool", target: "AI Agent", sourceOutput: "ai_tool"},\n {type: "addConnection", source: "New Code Tool", target: "AI Agent", sourceOutput: "ai_tool"}\n]})', + '\n// ============ REMOVING PROPERTIES EXAMPLES ============', + '// Remove a simple property\nn8n_update_partial_workflow({id: "rm1", operations: [{type: "updateNode", nodeName: "HTTP Request", updates: {onError: undefined}}]})', + '// Migrate from deprecated continueOnFail to onError\nn8n_update_partial_workflow({id: "rm2", operations: [{type: "updateNode", nodeName: "HTTP Request", updates: {continueOnFail: undefined, onError: "continueErrorOutput"}}]})', + '// Remove nested property\nn8n_update_partial_workflow({id: "rm3", operations: [{type: "updateNode", nodeName: "API Request", updates: {"parameters.authentication": undefined}}]})', + '// Remove multiple properties\nn8n_update_partial_workflow({id: "rm4", operations: [{type: "updateNode", nodeName: "Data Processor", updates: {continueOnFail: undefined, alwaysOutputData: undefined, "parameters.legacy_option": undefined}}]})', + '// Remove entire array property\nn8n_update_partial_workflow({id: "rm5", operations: [{type: "updateNode", nodeName: "HTTP Request", updates: {"parameters.headers": undefined}}]})' ], useCases: [ 'Rewire connections when replacing nodes', @@ -259,7 +373,11 @@ Please choose a different name. 'Connect language model BEFORE adding AI Agent to ensure validation passes', 'Use targetIndex for fallback models (primary=0, fallback=1)', 'Batch AI component connections in a single operation for atomicity', - 'Validate AI workflows after connection changes to catch configuration errors' + 'Validate AI workflows after connection changes to catch configuration errors', + 'To remove properties, set them to undefined (not null) in the updates object', + 'When migrating from deprecated properties, remove the old property and add the new one in the same operation', + 'Use undefined to resolve mutual exclusivity validation errors between properties', + 'Batch multiple property removals in a single updateNode operation for efficiency' ], pitfalls: [ '**REQUIRES N8N_API_URL and N8N_API_KEY environment variables** - will not work without n8n API access', @@ -279,7 +397,12 @@ Please choose a different name. '**Auto-sanitization behavior**: Binary operators (equals, contains) automatically have singleValue removed; unary operators (isEmpty, isNotEmpty) automatically get singleValue:true added', '**Auto-sanitization runs on ALL nodes**: When ANY update is made, ALL nodes in the workflow are sanitized (not just modified ones)', '**Auto-sanitization cannot fix everything**: It fixes operator structures and missing metadata, but cannot fix broken connections or branch mismatches', - '**Corrupted workflows beyond repair**: Workflows in paradoxical states (API returns corrupt, API rejects updates) cannot be fixed via API - must be recreated' + '**Corrupted workflows beyond repair**: Workflows in paradoxical states (API returns corrupt, API rejects updates) cannot be fixed via API - must be recreated', + 'Setting a property to null does NOT remove it - use undefined instead', + 'When properties are mutually exclusive (e.g., continueOnFail and onError), setting only the new property will fail - you must remove the old one with undefined', + 'Removing a required property may cause validation errors - check node documentation first', + 'Nested property removal with dot notation only removes the specific nested field, not the entire parent object', + 'Array index notation (e.g., "parameters.headers[0]") is not supported - remove the entire array property instead' ], relatedTools: ['n8n_update_full_workflow', 'n8n_get_workflow', 'validate_workflow', 'tools_documentation'] }