n8n-io/n8n · error
Failed to load existing workflow
Error message
Failed to load existing workflow ${workflowId} to preserve webhook IDs: ${message} What it means
ensureWebhookIds attempted to load the existing workflow to carry webhookIds over by node name (keeping URLs stable across rebuilds), but the load threw. The failure is surfaced with the underlying message so the caller knows IDs could not be preserved rather than being silently regenerated.
Solutions
- Confirm the workflow id exists and the service can read it
- Retry after fixing the underlying load error so webhook IDs can be reconciled
Defensive patterns
Strategy: try-catch
When it happens
Trigger: Thrown at packages/@n8n/instance-ai/src/tools/workflows/workflow-json-utils.ts:153 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/b27e557c65cd3b45.
Report an issue: GitHub.
Appendix: source
Thrown at packages/@n8n/instance-ai/src/tools/workflows/workflow-json-utils.ts:153
* For updates, preserve existing webhookIds by node name so URLs remain stable.
*/
export async function ensureWebhookIds(
json: WorkflowJSON,
workflowId: string | undefined,
ctx: InstanceAiContext,
): Promise<void> {
const existingWebhookIds = new Map<string, string>();
if (workflowId) {
try {
const existing = await ctx.workflowService.getAsWorkflowJSON(workflowId);
for (const node of existing.nodes ?? []) {
if (node.webhookId && node.name) {
existingWebhookIds.set(node.name, node.webhookId);
}
}
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
throw new Error(
`Failed to load existing workflow ${workflowId} to preserve webhook IDs: ${message}`,
{ cause: error },
);
}
}
for (const node of json.nodes ?? []) {
if (WEBHOOK_NODE_TYPES.has(node.type) && !node.webhookId) {
node.webhookId = (node.name && existingWebhookIds.get(node.name)) ?? randomUUID();
}
}
}
/**
* For updates, preserve existing node-group IDs by group name. The sandbox SDK
* build has no view of the saved workflow, so toJSON() mints a fresh deterministic
* ID for every group — overwriting the stable ID of a group the user created in
* the editor. Reconciling by name here keeps it stable, mirroring ensureWebhookIds.View on GitHub (pinned to 5ac6606e81)