mirror of
https://github.com/czlonkowski/n8n-mcp.git
synced 2026-03-23 19:03:07 +00:00
fix(p0): remove incorrect node type normalization before n8n API calls
## Bug Description
handleCreateWorkflow and handleUpdateFullWorkflow were incorrectly
normalizing node types from FULL form (n8n-nodes-base.webhook) to
SHORT form (nodes-base.webhook) before validation and API calls.
This caused 100% failure rate for workflow creation because:
- n8n API requires FULL form (n8n-nodes-base.*)
- Database stores SHORT form (nodes-base.*)
- NodeTypeNormalizer converts TO SHORT form (for database)
- But was being used BEFORE API calls (incorrect)
## Root Cause
NodeTypeNormalizer was designed for database lookups but was
incorrectly applied to API operations. The method name
`normalizeToFullForm()` is misleading - it actually normalizes
TO SHORT form.
## Changes
1. handlers-n8n-manager.ts:
- Removed NodeTypeNormalizer.normalizeWorkflowNodeTypes() from
handleCreateWorkflow (line 288)
- Removed normalization from handleUpdateFullWorkflow (line 544-557)
- Added proactive SHORT form detection with helpful errors
- Added comments explaining n8n API expects FULL form
2. node-type-normalizer.ts:
- Added prominent WARNING about not using before API calls
- Added examples showing CORRECT vs INCORRECT usage
- Clarified this is FOR DATABASE OPERATIONS ONLY
3. handlers-n8n-manager.test.ts:
- Fixed test to expect FULL form (not SHORT) sent to API
- Removed incorrect expectedNormalizedInput assertion
4. NEW: workflow-creation-node-type-format.test.ts:
- 7 integration tests with real validation (unmocked)
- Tests FULL form acceptance, SHORT form rejection
- Tests real-world workflows (webhook, schedule trigger)
- Regression test to prevent bug reintroduction
## Verification
Before fix:
❌ Manual Trigger → Set: FAILED
❌ Webhook → HTTP Request: FAILED
Failure rate: 100%
After fix:
✅ Manual Trigger → Set: SUCCESS (ID: kTAaDZwdpzj8gqzM)
✅ Webhook → HTTP Request: SUCCESS (ID: aPtQUb54uuHIqX52)
✅ All 39 tests passing (32 unit + 7 integration)
Success rate: 100%
## Impact
- Fixes: Complete blocking bug preventing all workflow creation
- Risk: Zero (removing buggy behavior)
- Breaking: None (external API unchanged)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,27 +1,44 @@
|
||||
/**
|
||||
* Universal Node Type Normalizer
|
||||
* Universal Node Type Normalizer - FOR DATABASE OPERATIONS ONLY
|
||||
*
|
||||
* Converts ANY node type variation to the canonical SHORT form used by the database.
|
||||
* This fixes the critical issue where AI agents or external sources may produce
|
||||
* full-form node types (e.g., "n8n-nodes-base.webhook") which need to be normalized
|
||||
* to match the database storage format (e.g., "nodes-base.webhook").
|
||||
* ⚠️ WARNING: Do NOT use before n8n API calls!
|
||||
*
|
||||
* This class converts node types to SHORT form (database format).
|
||||
* The n8n API requires FULL form (n8n-nodes-base.*).
|
||||
*
|
||||
* **Use this ONLY when:**
|
||||
* - Querying the node database
|
||||
* - Searching for node information
|
||||
* - Looking up node metadata
|
||||
*
|
||||
* **Do NOT use before:**
|
||||
* - Creating workflows (n8n_create_workflow)
|
||||
* - Updating workflows (n8n_update_workflow)
|
||||
* - Any n8n API calls
|
||||
*
|
||||
* **IMPORTANT:** The n8n-mcp database stores nodes in SHORT form:
|
||||
* - n8n-nodes-base → nodes-base
|
||||
* - @n8n/n8n-nodes-langchain → nodes-langchain
|
||||
*
|
||||
* Handles:
|
||||
* - Full form → Short form (n8n-nodes-base.X → nodes-base.X)
|
||||
* - Already short form → Unchanged
|
||||
* - LangChain nodes → Proper short prefix
|
||||
* But the n8n API requires FULL form:
|
||||
* - nodes-base → n8n-nodes-base
|
||||
* - nodes-langchain → @n8n/n8n-nodes-langchain
|
||||
*
|
||||
* @example
|
||||
* NodeTypeNormalizer.normalizeToFullForm('n8n-nodes-base.webhook')
|
||||
* @example Database Lookup (CORRECT usage)
|
||||
* const dbType = NodeTypeNormalizer.normalizeToFullForm('n8n-nodes-base.webhook')
|
||||
* // → 'nodes-base.webhook'
|
||||
* const node = await repository.getNode(dbType)
|
||||
*
|
||||
* @example
|
||||
* NodeTypeNormalizer.normalizeToFullForm('nodes-base.webhook')
|
||||
* // → 'nodes-base.webhook' (unchanged)
|
||||
* @example API Call (INCORRECT - Do NOT do this!)
|
||||
* const workflow = { nodes: [{ type: 'n8n-nodes-base.webhook' }] }
|
||||
* const normalized = NodeTypeNormalizer.normalizeWorkflowNodeTypes(workflow)
|
||||
* // ❌ WRONG! normalized has SHORT form, API needs FULL form
|
||||
* await client.createWorkflow(normalized) // FAILS!
|
||||
*
|
||||
* @example API Call (CORRECT)
|
||||
* const workflow = { nodes: [{ type: 'n8n-nodes-base.webhook' }] }
|
||||
* // ✅ Send as-is to API (FULL form required)
|
||||
* await client.createWorkflow(workflow) // WORKS!
|
||||
*/
|
||||
|
||||
export interface NodeTypeNormalizationResult {
|
||||
|
||||
Reference in New Issue
Block a user