mirror of
https://github.com/czlonkowski/n8n-mcp.git
synced 2026-02-06 05:23:08 +00:00
fix(issue-248): use unconditional empty settings object for cloud API compatibility
Issue #248 required three iterations to solve due to n8n API version differences: 1. First attempt: Whitelist filtering - Failed: API rejects ANY settings properties via update endpoint 2. Second attempt: Complete settings removal - Failed: Cloud API requires settings property to exist 3. Final solution: Unconditional empty settings object - Success: Satisfies both API requirements Changes: - src/services/n8n-validation.ts:153 - Changed from conditional `if (cleanedWorkflow.settings)` to unconditional - Always sets `cleanedWorkflow.settings = {}` - Works for both cloud (requires property) and self-hosted (rejects properties) - tests/unit/services/n8n-validation.test.ts - Updated all 4 tests to expect `settings: {}` instead of removed settings - Tests verify empty object approach works for all scenarios Tested: - ✅ localhost workflow (wwTodXf1jbUy3Ja5) - ✅ cloud workflow (n8n.estyl.team/workflow/WKFeCRUjTeYbYhTf) - ✅ All 72 unit tests passing References: - https://community.n8n.io/t/api-workflow-update-endpoint-doesnt-support-setting-callerpolicy/161916 - Tested with @agent-n8n-mcp-tester on production workflows
This commit is contained in:
@@ -344,12 +344,12 @@ describe('n8n-validation', () => {
|
||||
expect(cleaned).not.toHaveProperty('shared');
|
||||
expect(cleaned).not.toHaveProperty('active');
|
||||
|
||||
// Should keep name but remove settings (n8n API limitation)
|
||||
// Should keep name but replace settings with empty object (n8n API limitation)
|
||||
expect(cleaned.name).toBe('Updated Workflow');
|
||||
expect(cleaned).not.toHaveProperty('settings');
|
||||
expect(cleaned.settings).toEqual({});
|
||||
});
|
||||
|
||||
it('should not add default settings for update', () => {
|
||||
it('should add empty settings object for cloud API compatibility', () => {
|
||||
const workflow = {
|
||||
name: 'Test Workflow',
|
||||
nodes: [],
|
||||
@@ -357,10 +357,10 @@ describe('n8n-validation', () => {
|
||||
} as any;
|
||||
|
||||
const cleaned = cleanWorkflowForUpdate(workflow);
|
||||
expect(cleaned).not.toHaveProperty('settings');
|
||||
expect(cleaned.settings).toEqual({});
|
||||
});
|
||||
|
||||
it('should remove settings entirely to prevent API errors (Issue #248 - corrected fix)', () => {
|
||||
it('should replace settings with empty object to prevent API errors (Issue #248 - final fix)', () => {
|
||||
const workflow = {
|
||||
name: 'Test Workflow',
|
||||
nodes: [],
|
||||
@@ -375,11 +375,11 @@ describe('n8n-validation', () => {
|
||||
|
||||
const cleaned = cleanWorkflowForUpdate(workflow);
|
||||
|
||||
// Settings should be removed entirely (n8n API doesn't support updating settings)
|
||||
expect(cleaned).not.toHaveProperty('settings');
|
||||
// Settings replaced with empty object (satisfies both API versions)
|
||||
expect(cleaned.settings).toEqual({});
|
||||
});
|
||||
|
||||
it('should remove settings with callerPolicy (Issue #248 - API limitation)', () => {
|
||||
it('should replace settings with callerPolicy (Issue #248 - API limitation)', () => {
|
||||
const workflow = {
|
||||
name: 'Test Workflow',
|
||||
nodes: [],
|
||||
@@ -393,11 +393,11 @@ describe('n8n-validation', () => {
|
||||
|
||||
const cleaned = cleanWorkflowForUpdate(workflow);
|
||||
|
||||
// Settings must be removed (n8n API rejects updates with settings properties)
|
||||
expect(cleaned).not.toHaveProperty('settings');
|
||||
// Settings replaced with empty object (n8n API rejects updates with settings properties)
|
||||
expect(cleaned.settings).toEqual({});
|
||||
});
|
||||
|
||||
it('should remove all settings regardless of content (Issue #248 - API design)', () => {
|
||||
it('should replace all settings regardless of content (Issue #248 - API design)', () => {
|
||||
const workflow = {
|
||||
name: 'Test Workflow',
|
||||
nodes: [],
|
||||
@@ -417,9 +417,9 @@ describe('n8n-validation', () => {
|
||||
|
||||
const cleaned = cleanWorkflowForUpdate(workflow);
|
||||
|
||||
// Settings removed due to n8n API limitation (cannot update settings via API)
|
||||
// Settings replaced with empty object due to n8n API limitation (cannot update settings via API)
|
||||
// See: https://community.n8n.io/t/api-workflow-update-endpoint-doesnt-support-setting-callerpolicy/161916
|
||||
expect(cleaned).not.toHaveProperty('settings');
|
||||
expect(cleaned.settings).toEqual({});
|
||||
});
|
||||
|
||||
it('should handle workflows without settings gracefully', () => {
|
||||
@@ -430,7 +430,7 @@ describe('n8n-validation', () => {
|
||||
} as any;
|
||||
|
||||
const cleaned = cleanWorkflowForUpdate(workflow);
|
||||
expect(cleaned).not.toHaveProperty('settings');
|
||||
expect(cleaned.settings).toEqual({});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1309,7 +1309,7 @@ describe('n8n-validation', () => {
|
||||
expect(forUpdate).not.toHaveProperty('active');
|
||||
expect(forUpdate).not.toHaveProperty('tags');
|
||||
expect(forUpdate).not.toHaveProperty('meta');
|
||||
expect(forUpdate).not.toHaveProperty('settings'); // Should not add defaults for update
|
||||
expect(forUpdate.settings).toEqual({}); // Settings replaced with empty object for API compatibility
|
||||
expect(validateWorkflowStructure(forUpdate)).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user