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:
czlonkowski
2025-10-04 18:45:58 +02:00
parent 1db9ecf33f
commit ecf0d50a63
2 changed files with 36 additions and 9 deletions

View File

@@ -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;
} }

View File

@@ -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
); );