mirror of
https://github.com/czlonkowski/n8n-mcp.git
synced 2026-02-06 13:33:11 +00:00
fix: resolve Phase 4 test failures
Root cause analysis:
1. n8n API requires settings field in ALL update requests (per OpenAPI spec)
2. Previous cleanWorkflowForUpdate always set settings={} which prevented updates
Fixes:
1. Add settings field to "Update Connections" test
2. Update cleanWorkflowForUpdate to filter settings instead of overwriting:
- If settings provided: filter to OpenAPI spec whitelisted properties
- If no settings: use empty object {} for backwards compatibility
- Maintains fix for Issue #248 by filtering out unsafe properties like callerPolicy
This allows settings updates while preventing version-specific API errors.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -139,18 +139,44 @@ export function cleanWorkflowForUpdate(workflow: Workflow): Partial<Workflow> {
|
|||||||
// PROBLEM:
|
// PROBLEM:
|
||||||
// - Some versions reject updates with settings properties (community forum reports)
|
// - Some versions reject updates with settings properties (community forum reports)
|
||||||
// - Cloud versions REQUIRE settings property to be present (n8n.estyl.team)
|
// - Cloud versions REQUIRE settings property to be present (n8n.estyl.team)
|
||||||
// - Properties like callerPolicy and executionOrder cause "additional properties" errors
|
// - Properties like callerPolicy cause "additional properties" errors
|
||||||
//
|
//
|
||||||
// SOLUTION:
|
// SOLUTION:
|
||||||
// - ALWAYS set settings to empty object {}, regardless of whether it exists
|
// - Filter settings to only include whitelisted properties (OpenAPI spec)
|
||||||
|
// - If no settings provided, use empty object {} for safety
|
||||||
// - Empty object satisfies "required property" validation (cloud API)
|
// - Empty object satisfies "required property" validation (cloud API)
|
||||||
// - Empty object has no "additional properties" to trigger errors (self-hosted)
|
// - Whitelisted properties prevent "additional properties" errors
|
||||||
// - n8n API interprets empty settings as "no changes" and preserves existing settings
|
|
||||||
//
|
//
|
||||||
// References:
|
// References:
|
||||||
// - https://community.n8n.io/t/api-workflow-update-endpoint-doesnt-support-setting-callerpolicy/161916
|
// - https://community.n8n.io/t/api-workflow-update-endpoint-doesnt-support-setting-callerpolicy/161916
|
||||||
|
// - OpenAPI spec: workflowSettings schema
|
||||||
// - Tested on n8n.estyl.team (cloud) and localhost (self-hosted)
|
// - Tested on n8n.estyl.team (cloud) and localhost (self-hosted)
|
||||||
cleanedWorkflow.settings = {};
|
|
||||||
|
// Whitelisted settings properties from n8n OpenAPI spec
|
||||||
|
const safeSettingsProperties = [
|
||||||
|
'saveExecutionProgress',
|
||||||
|
'saveManualExecutions',
|
||||||
|
'saveDataErrorExecution',
|
||||||
|
'saveDataSuccessExecution',
|
||||||
|
'executionTimeout',
|
||||||
|
'errorWorkflow',
|
||||||
|
'timezone',
|
||||||
|
'executionOrder'
|
||||||
|
];
|
||||||
|
|
||||||
|
if (cleanedWorkflow.settings && typeof cleanedWorkflow.settings === 'object') {
|
||||||
|
// Filter to only safe properties
|
||||||
|
const filteredSettings: any = {};
|
||||||
|
for (const key of safeSettingsProperties) {
|
||||||
|
if (key in cleanedWorkflow.settings) {
|
||||||
|
filteredSettings[key] = (cleanedWorkflow.settings as any)[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cleanedWorkflow.settings = filteredSettings;
|
||||||
|
} else {
|
||||||
|
// No settings provided - use empty object for safety
|
||||||
|
cleanedWorkflow.settings = {};
|
||||||
|
}
|
||||||
|
|
||||||
return cleanedWorkflow;
|
return cleanedWorkflow;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,16 +166,17 @@ describe('Integration: handleUpdateWorkflow', () => {
|
|||||||
if (!created.id) throw new Error('Workflow ID is missing');
|
if (!created.id) throw new Error('Workflow ID is missing');
|
||||||
context.trackWorkflow(created.id);
|
context.trackWorkflow(created.id);
|
||||||
|
|
||||||
// Fetch current workflow to get nodes (required by n8n API)
|
// Fetch current workflow to get required fields (n8n API requirement)
|
||||||
const current = await client.getWorkflow(created.id);
|
const current = await client.getWorkflow(created.id);
|
||||||
|
|
||||||
// Remove connections (disconnect nodes)
|
// Remove connections (disconnect nodes)
|
||||||
const response = await handleUpdateWorkflow(
|
const response = await handleUpdateWorkflow(
|
||||||
{
|
{
|
||||||
id: created.id,
|
id: created.id,
|
||||||
name: current.name, // Required by n8n API
|
name: current.name, // Required by n8n API
|
||||||
nodes: current.nodes, // Required by n8n API
|
nodes: current.nodes, // Required by n8n API
|
||||||
connections: {}
|
connections: {},
|
||||||
|
settings: current.settings // Required by n8n API
|
||||||
},
|
},
|
||||||
mcpContext
|
mcpContext
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user