Skip to content

fix(ai-builder): Hide and reap intermediate AI-created workflows (backport to release-candidate/2.18.x)#29344

Merged
aalises merged 5 commits intorelease-candidate/2.18.xfrom
backport-29066-to-release-candidate/2.18.x
Apr 28, 2026
Merged

fix(ai-builder): Hide and reap intermediate AI-created workflows (backport to release-candidate/2.18.x)#29344
aalises merged 5 commits intorelease-candidate/2.18.xfrom
backport-29066-to-release-candidate/2.18.x

Conversation

@n8n-assistant
Copy link
Copy Markdown
Contributor

@n8n-assistant n8n-assistant Bot commented Apr 27, 2026

Description

Backport of #29066 to release-candidate/2.18.x.

Checklist for the author (@aalises) to go through.

  • Review the backport changes
  • Fix possible conflicts
  • Merge to target branch

After this PR has been merged, it will be picked up in the next patch release for release track.

Original description

Summary

The AI builder leaves intermediate workflows behind in two scenarios (INS-24):

  1. Orphans from failed builds — a task partially saves a workflow then fails or is cancelled.
  2. Stepping-stones — chunks, sub-workflows, scratch attempts, or workflows obsoleted by a replan that the agent never references again.

Both surface in the user's workflows list as half-built clutter the user didn't ask for.

How it works

  • meta.aiTemporary: true is stamped on every workflow the AI builder creates (submit-workflow + build-workflow, only on create — never on update so user-authored workflows are untouched). No DB migration: meta is already a nullable JSON column.
  • The default workflows list query hides stamped rows (postgres + sqlite). The user never sees an in-progress stepping-stone.
  • The orchestrator clears the stamp on mainWorkflowAttempt.workflowId at the end of every successful build — the deliverable is now indistinguishable from a user workflow.
  • At every run-finish (success / cancel / error), the platform iterates the run's in-memory created-set and calls archiveIfAiTemporary on each id. Atomic check-and-archive: anything still stamped (chunks, scratch, obsoleted-by-replan) gets soft-deleted; the main survives because its stamp was cleared.

Artifacts panel UX

The artifacts panel keeps stepping-stones visible in the conversation history after the run ends — but they've been archived, so clicking them would lead to a dead preview. To close that loop:

  • run-finish events carry archivedWorkflowIds: string[] — the ids the reap just soft-deleted.
  • The frontend store accumulates them per thread and tags matching entries in the resource registry as archived: true.
  • The artifacts panel rows, and the ArtifactCard used by the activity tree and timeline, render archived entries dimmed with a strikethrough name and an "Archived" pill.

Why this shape

  • Resume paths, crashes, abandoned sessions, direct build-workflow-with-agent calls — every code path that could leak a stepping-stone reduces to a single SQL predicate.
  • The agent's prompt carries no cleanup instructions — the platform owns the lifecycle, not the model.
  • Soft delete (archive) — a mistaken reap is recoverable from the archive view.

Crash leaks (process dies mid-run before run-finish fires) are accepted as known: invisible to the user (list filter) and rare. Easy to add a one-off admin sweep later if it ever materializes.

Related Linear tickets, Github issues, and Community forum posts

https://linear.app/n8n/issue/INS-24

Review / Merge checklist

  • I have seen this code, I have run this code, and I take responsibility for this code.
  • PR title and summary are descriptive. (conventions)
  • Docs updated or follow-up ticket created.
  • Tests included.
  • PR Labeled with `Backport to Beta`, `Backport to Stable`, or `Backport to v1` (if the PR is an urgent fix that needs to be backported)

@n8n-assistant n8n-assistant Bot added automation:backport core Enhancement outside /nodes-base and /editor-ui n8n team Authored by the n8n team labels Apr 27, 2026
@n8n-assistant n8n-assistant Bot requested a review from aalises April 27, 2026 15:49
@n8n-assistant
Copy link
Copy Markdown
Contributor Author

n8n-assistant Bot commented Apr 27, 2026

Please cherry-pick the changes locally and resolve any conflicts.

git fetch origin backport-29066-to-release-candidate/2.18.x
git worktree add --checkout .worktree/backport-29066-to-release-candidate/2.18.x backport-29066-to-release-candidate/2.18.x
cd .worktree/backport-29066-to-release-candidate/2.18.x
git reset --hard HEAD^
git cherry-pick -x 632ae67de3fa33487e1ad513043cf740cb32bb1a
git push --force-with-lease

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 27, 2026

Performance Comparison

Comparing currentlatest master14-day baseline

Memory consumption baseline with starter plan resources

Metric Current Latest Master Baseline (avg) vs Master vs Baseline Status
memory-heap-used-baseline 114.63 MB 118.98 MB 115.72 MB (σ 2.02) -3.7% -0.9%
memory-rss-baseline 281.54 MB 293.85 MB 291.38 MB (σ 29.40) -4.2% -3.4%

Idle baseline with Instance AI module loaded

Metric Current Latest Master Baseline (avg) vs Master vs Baseline Status
instance-ai-heap-used-baseline 187.39 MB 191.65 MB 187.79 MB (σ 2.07) -2.2% -0.2%
instance-ai-rss-baseline 341.36 MB 354.18 MB 364.79 MB (σ 21.08) -3.6% -6.4% ⚠️

docker-stats

Metric Current Latest Master Baseline (avg) vs Master vs Baseline Status
docker-image-size-n8n 1269.76 MB 1300.48 MB 1303.55 MB (σ 51.48) -2.4% -2.6%
docker-image-size-runners 386.00 MB 388.00 MB 391.15 MB (σ 9.26) -0.5% -1.3%
How to read this table
  • Current: This PR's value (or latest master if PR perf tests haven't run)
  • Latest Master: Most recent nightly master measurement
  • Baseline: Rolling 14-day average from master
  • vs Master: PR impact (current vs latest master)
  • vs Baseline: Drift from baseline (current vs rolling avg)
  • Status: ✅ within 1σ | ⚠️ 1-2σ | 🔴 >2σ regression

@aalises aalises marked this pull request as ready for review April 27, 2026 19:28
@aalises aalises requested a review from a team as a code owner April 27, 2026 19:28
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5 issues found across 30 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/frontend/editor-ui/src/features/ai/instanceAi/components/AgentActivityTree.vue">

<violation number="1" location="packages/frontend/editor-ui/src/features/ai/instanceAi/components/AgentActivityTree.vue:94">
P0: Unresolved merge conflict markers were committed in the Vue template, which will break compilation.</violation>
</file>

<file name="packages/frontend/@n8n/i18n/src/locales/en.json">

<violation number="1" location="packages/frontend/@n8n/i18n/src/locales/en.json:5151">
P0: Remove unresolved merge-conflict markers from the locale JSON file; they make `en.json` invalid JSON.</violation>
</file>

<file name="packages/@n8n/instance-ai/src/storage/__tests__/planned-task-storage.test.ts">

<violation number="1" location="packages/@n8n/instance-ai/src/storage/__tests__/planned-task-storage.test.ts:6">
P2: Move this mock state inside the factory or rename it to a `mock*` variable so Jest can hoist the mock without hitting the out-of-scope variable restriction.</violation>
</file>

<file name="packages/frontend/editor-ui/src/features/ai/instanceAi/instanceAi.store.ts">

<violation number="1" location="packages/frontend/editor-ui/src/features/ai/instanceAi/instanceAi.store.ts:521">
P2: Clearing `archivedWorkflowIds` on thread reset drops archived artifact state when returning to a previously viewed thread, because hydration does not repopulate archived IDs.</violation>
</file>

<file name="packages/@n8n/db/src/repositories/workflow.repository.ts">

<violation number="1" location="packages/@n8n/db/src/repositories/workflow.repository.ts:886">
P2: The AI-temporary filter is applied unconditionally, so archived list queries (`isArchived: true`) also hide AI-created archived workflows. This prevents those workflows from being visible/recoverable in archive views.</violation>
</file>
Architecture diagram
sequenceDiagram
    participant UI as Client (Frontend Store/UI)
    participant AIS as InstanceAiService
    participant Adapter as InstanceAiAdapterService
    participant TWR as NEW: AiBuilderTemporaryWorkflowRepository
    participant DB as Database (Workflow Table)

    Note over UI, DB: AI Workflow Creation & Marking
    UI->>AIS: Start AI Run (chat/replan)
    AIS->>Adapter: Create intermediate workflow (stepping-stone)
    Adapter->>DB: Insert workflow record
    Adapter->>TWR: NEW: mark(workflowId, threadId)
    TWR->>DB: Insert into ai_builder_temporary_workflow
    
    Note over UI, DB: List Filtering (Concurrent Request)
    UI->>DB: GET /workflows (User list)
    DB->>DB: CHANGED: Filter WHERE NOT EXISTS in temporary_marker_table
    DB-->>UI: Workflow list (intermediate AI workflows hidden)

    Note over UI, DB: Main Workflow Promotion
    AIS->>AIS: Identify successful main workflow
    AIS->>Adapter: NEW: clearAiTemporary(workflowId)
    Adapter->>TWR: NEW: unmark(workflowId)
    TWR->>DB: DELETE FROM ai_builder_temporary_workflow

    Note over UI, DB: Run Finish & Reaping (Success or Error)
    AIS->>AIS: handleRunFinish()
    AIS->>TWR: NEW: findByThread(threadId)
    TWR-->>AIS: List of remaining marked workflowIds
    
    loop For each marked ID (Stepping-stones)
        AIS->>Adapter: NEW: archiveIfAiTemporary(workflowId)
        Adapter->>DB: CHANGED: Soft-delete (archive) workflow
        Adapter->>TWR: NEW: unmark(workflowId)
    end

    Note over UI, DB: UI Synchronization
    AIS-->>UI: CHANGED: Event: "run-finish" (includes archivedWorkflowIds[])
    UI->>UI: NEW: Update ResourceRegistry (archived: true)
    UI->>UI: CHANGED: Render archived ArtifactCards dimmed/strikethrough
Loading

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.

Comment on lines +94 to +98
<<<<<<< HEAD
=======
:archived="store.producedArtifacts.get(artifact.resourceId)?.archived"
:class="$style.artifactCard"
>>>>>>> 632ae67de3 (fix(ai-builder): Hide and reap intermediate AI-created workflows (#29066))
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0: Unresolved merge conflict markers were committed in the Vue template, which will break compilation.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/frontend/editor-ui/src/features/ai/instanceAi/components/AgentActivityTree.vue, line 94:

<comment>Unresolved merge conflict markers were committed in the Vue template, which will break compilation.</comment>

<file context>
@@ -91,6 +91,11 @@ function resolveArtifactName(artifact: ArtifactInfo): string {
 					:name="resolveArtifactName(artifact)"
 					:resource-id="artifact.resourceId"
 					:project-id="artifact.projectId"
+<<<<<<< HEAD
+=======
+					:archived="store.producedArtifacts.get(artifact.resourceId)?.archived"
</file context>
Suggested change
<<<<<<< HEAD
=======
:archived="store.producedArtifacts.get(artifact.resourceId)?.archived"
:class="$style.artifactCard"
>>>>>>> 632ae67de3 (fix(ai-builder): Hide and reap intermediate AI-created workflows (#29066))
:archived="store.producedArtifacts.get(artifact.resourceId)?.archived"
:class="$style.artifactCard"
Fix with Cubic

Comment on lines +5151 to +5157
<<<<<<< HEAD
=======
"instanceAi.artifactsPanel.archived": "Archived",
"instanceAi.previewTabBar.collapse": "Collapse panel",
"instanceAi.previewTabBar.openInEditor": "Open in editor",
"instanceAi.previewTabBar.copyLink": "Copy link",
>>>>>>> 632ae67de3 (fix(ai-builder): Hide and reap intermediate AI-created workflows (#29066))
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0: Remove unresolved merge-conflict markers from the locale JSON file; they make en.json invalid JSON.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/frontend/@n8n/i18n/src/locales/en.json, line 5151:

<comment>Remove unresolved merge-conflict markers from the locale JSON file; they make `en.json` invalid JSON.</comment>

<file context>
@@ -5148,6 +5148,13 @@
 	"instanceAi.artifactsPanel.noArtifacts": "No artifacts yet",
 	"instanceAi.artifactsPanel.tasks": "Tasks",
 	"instanceAi.artifactsPanel.openWorkflow": "Open",
+<<<<<<< HEAD
+=======
+	"instanceAi.artifactsPanel.archived": "Archived",
</file context>
Suggested change
<<<<<<< HEAD
=======
"instanceAi.artifactsPanel.archived": "Archived",
"instanceAi.previewTabBar.collapse": "Collapse panel",
"instanceAi.previewTabBar.openInEditor": "Open in editor",
"instanceAi.previewTabBar.copyLink": "Copy link",
>>>>>>> 632ae67de3 (fix(ai-builder): Hide and reap intermediate AI-created workflows (#29066))
"instanceAi.artifactsPanel.archived": "Archived",
"instanceAi.previewTabBar.collapse": "Collapse panel",
"instanceAi.previewTabBar.openInEditor": "Open in editor",
"instanceAi.previewTabBar.copyLink": "Copy link",
Fix with Cubic

Comment thread packages/frontend/editor-ui/src/features/ai/instanceAi/instanceAi.store.ts Outdated
Comment thread packages/@n8n/db/src/repositories/workflow.repository.ts Outdated
aalises added 2 commits April 27, 2026 21:47
- workflow.repository.ts: skip the AI-temporary filter when listing
  archived workflows so reaped AI-created workflows remain visible in
  the archive view.
- instanceAi.store.ts: scope archivedWorkflowIds per thread so the
  archived state survives thread switches instead of being cleared on
  every reset.
- planned-task-storage.test.ts: rename metadataByThread to
  mockMetadataByThread so jest can hoist the mock factory without
  hitting the out-of-scope variable restriction.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 27, 2026

Instance AI Workflow Eval Results

8/8 built | 12/27 passed (44%)

Workflow Build Passed
Create a workflow that handles contact form submissions via a webhook. 2/5
Get all the Linear issues created in the last 2 weeks. Filter them for 3/5
Every day, get the posts made in the past day on 3 different Slack cha 3/5
Create a form that collects: name, email, company, and interest level 2/2
Every day, fetch all open GitHub issues from repository 'acme-corp/bac 0/2
Create a workflow that receives webhook notifications with a JSON body 0/3
Fetch the latest posts from the JSONPlaceholder API (GET https://jsonp 2/3
Every hour, check the current weather for London, New York, and Tokyo 0/2
Failure details

missing-fields

Error: The operation was aborted due to timeout

partial-action-failure [builder_issue]

The workflow crashed entirely when the Telegram Notification node returned a 400 error ('Bad Request: chat not found'). The workflow has no error handling (no try/catch, no error branch, no 'Continue

invalid-email [builder_issue]

The workflow crashed entirely when the Auto-Reply Email node threw 'Invalid email address (item 0)' because the Gmail node validates the recipient email before making any HTTP request, and 'not-an-ema

multi-team-creator [builder_issue]

The checklist requires: (1) Alice's AI issue is excluded (not cross-team), (2) Alice has more cross-team issues than Bob, (3) report sorted descending with Alice first.

The scenario data states Alice

api-error [builder_issue]

The workflow crashed with 'Authorization failed - please check your credentials' when the Linear API returned an authentication error. The error propagated uncaught — there is no error handling branch

channel-not-found [builder_issue]

The workflow does not handle the channel_not_found error gracefully. When 'Slack: Get #product' returned an error response, the workflow halted entirely with the error 'Slack error response: channel_n

insufficient-permissions [builder_issue]

The workflow does not handle the permission error gracefully. When 'Slack: Get #product' returns a 'not_in_channel' error, the workflow crashes entirely with the error 'Slack error response: not_in_ch

happy-path [builder_issue]

The workflow failed to execute. The 'Split Issues' node has an empty 'fieldToSplitOut' parameter — the required 'Fields To Split Out' field was not configured. This caused the execution to fail immedi

no-bugs [builder_issue]

The workflow failed to execute cleanly. The 'Split Issues' node has a misconfigured 'fieldToSplitOut' parameter (empty string, which is required). This caused the execution to fail entirely with the e

high-priority [builder_issue]

The Route by Level Switch node correctly matched the 'high' level and produced output on its first (high) branch. However, the Connections JSON shows that Route by Level has NO outgoing connections —

medium-priority [builder_issue]

The Switch node (Route by Level) correctly identified the 'medium' level and output the data on its medium branch. However, the connections JSON shows that Route by Level has NO outgoing connections —

low-priority [builder_issue]

The workflow correctly routed the low-priority notification to output index 2 (the 'low' branch) of the Switch node, but the Send Gmail node did not run. Looking at the Connections JSON, the only conn

happy-path [builder_issue]

The workflow did not execute successfully end-to-end. The execution stopped after the Split Posts node, which produced no output (empty/none). This happened because the Split Posts node is configured

happy-path [builder_issue]

The workflow failed to execute. The pre-analysis flags a builder issue: the Airtable 'Log to Airtable' node has an invalid Table ID — 'Weather Logs' is a plain text name, not a valid Airtable Table ID

no-alerts [builder_issue]

The workflow failed to execute due to a builder configuration issue. The 'Log to Airtable' node has an invalid Table ID — the value 'Weather Logs' is a plain text name rather than a valid Airtable Tab

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 28, 2026

Bundle Report

Changes will increase total bundle size by 44.01kB (0.1%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
editor-ui-esm 45.8MB 44.01kB (0.1%) ⬆️

Affected Assets, Files, and Routes:

view changes for bundle: editor-ui-esm

Assets Changed:

Asset Name Size Change Total Size Change (%)
assets/constants-*.js 664 bytes 3.14MB 0.02%
assets/src-*.js 1.0kB 2.43MB 0.04%
assets/index-*.js 1.19kB 1.31MB 0.09%
assets/users.store-*.js -2 bytes 1.06MB -0.0%
assets/core-*.js 1.33kB 629.53kB 0.21%
assets/InstanceAiView-*.js 9.78kB 361.42kB 2.78%
assets/InstanceAiView-*.css 7.66kB 174.7kB 4.59%
assets/usePostMessageHandler-*.js 74 bytes 137.93kB 0.05%
assets/useRootStore-*.js -257 bytes 131.07kB -0.2%
assets/WorkflowLayout-*.js 95 bytes 128.02kB 0.07%
assets/router-*.js 563 bytes 120.37kB 0.47%
assets/useCanvasOperations-*.js 90 bytes 95.47kB 0.09%
assets/ProjectSettings-*.js 303 bytes 74.37kB 0.41%
assets/CreditWarningBanner-*.js 872 bytes 58.99kB 1.5%
assets/AppSidebar-*.js -3.43kB 39.82kB -7.92%
assets/SettingsInstanceAiView-*.js -10.35kB 36.11kB -22.28%
assets/ProjectHeader-*.js -376 bytes 27.05kB -1.37%
assets/SettingsInstanceAiView-*.css -5.16kB 18.73kB -21.59%
assets/instanceAiSettings.store-*.js 2.8kB 18.53kB 17.82% ⚠️
assets/ComputerUseSetupContent-*.js (New) 18.03kB 18.03kB 100.0% 🚀
assets/AppSidebar-*.css -1.75kB 15.88kB -9.91%
assets/SettingsAiGatewayView-*.js 1.22kB 11.22kB 12.18% ⚠️
assets/OAuthConsentView-*.js -14 bytes 9.99kB -0.14%
assets/ProjectHeader-*.css -56 bytes 6.8kB -0.82%
assets/ComputerUseSetupContent-*.css (New) 6.38kB 6.38kB 100.0% 🚀
assets/BrowserUseSetupModal-*.css (New) 5.96kB 5.96kB 100.0% 🚀
assets/SettingsAiGatewayView-*.css 141 bytes 4.1kB 3.56%
assets/BrowserUseSetupModal-*.js (New) 3.55kB 3.55kB 100.0% 🚀
assets/ComputerUseSetupModal-*.css (New) 2.7kB 2.7kB 100.0% 🚀
assets/useFreeAiCredits-*.js 37 bytes 2.22kB 1.69%
assets/ComputerUseSetupModal-*.js (New) 965 bytes 965 bytes 100.0% 🚀

Files in assets/InstanceAiView-*.js:

  • ./src/features/ai/instanceAi/components/AgentTimeline.vue → Total Size: 348 bytes

  • ./src/features/ai/instanceAi/components/InstanceAiArtifactsPanel.vue → Total Size: 392 bytes

  • ./src/features/ai/instanceAi/components/ArtifactCard.vue → Total Size: 344 bytes

  • ./src/features/ai/instanceAi/components/AgentActivityTree.vue → Total Size: 364 bytes

Files in assets/CreditWarningBanner-*.js:

  • ./src/features/ai/instanceAi/useResourceRegistry.ts → Total Size: 6.91kB

  • ./src/features/ai/instanceAi/instanceAi.store.ts → Total Size: 25.01kB

@aalises aalises enabled auto-merge (squash) April 28, 2026 07:52
@aalises aalises merged commit 1031603 into release-candidate/2.18.x Apr 28, 2026
46 checks passed
@aalises aalises deleted the backport-29066-to-release-candidate/2.18.x branch April 28, 2026 08:01
@n8n-assistant n8n-assistant Bot mentioned this pull request Apr 28, 2026
@n8n-assistant
Copy link
Copy Markdown
Contributor Author

n8n-assistant Bot commented Apr 29, 2026

Got released with n8n@2.18.5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automation:backport core Enhancement outside /nodes-base and /editor-ui n8n team Authored by the n8n team Released

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant