Skip to content

Instance AI workflow setup nodes groupping#29764

Open
scdekov wants to merge 5 commits intofeature/instance-ai-workflow-setup-rewritefrom
feature/instance-ai-workflow-setup-rewrite-pr4
Open

Instance AI workflow setup nodes groupping#29764
scdekov wants to merge 5 commits intofeature/instance-ai-workflow-setup-rewritefrom
feature/instance-ai-workflow-setup-rewrite-pr4

Conversation

@scdekov
Copy link
Copy Markdown
Member

@scdekov scdekov commented May 5, 2026

Summary

Grouping of instance ai setup requests based on:

  • Shared credentials
    • 2 nodes having the same credential type are merged only if the second node does not also has parameters to be setup
  • Parent/sub nodes eg model/tools/memory of an agent

Review notes:

  • Backend change: Added parentNode to the workflowSetupNodeSchema so that FE doesn't have to fetch the whole workflow in order to group based on parent/sub nodes
  • FE
    • Split the Cards rendering to WorkflowSetupCard and WorkflowSetupGroupCard, both using a new WorkflowSetupSectionBody component
    • Extracted WorkflowSetupWizardFooter from WorkflowSetupWizard as it's now reused for the group and non group card components
    • Think of setup section as an entity containing credential picker and/or parameter inputs for a node (the creds picker could be shared). Then setup step is either a card (single section) or cardGroup (one or more sections). "Cards" are responsible for the visualizing the step data
  • Ignore changes on the fixtures .json and .jsonl files

Related Linear tickets, Github issues, and Community forum posts

https://linear.app/n8n/issue/ADO-5119/add-cards-grouping

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 the n8n team Authored by the n8n team label May 5, 2026
@scdekov scdekov force-pushed the feature/instance-ai-workflow-setup-rewrite-pr4 branch from b8b07b6 to b3b3727 Compare May 5, 2026 10:10
@scdekov scdekov marked this pull request as ready for review May 5, 2026 10:26
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.

3 issues found across 102 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/workflowSetup/components/WorkflowSetupGroupCard.vue">

<violation number="1" location="packages/frontend/editor-ui/src/features/ai/instanceAi/workflowSetup/components/WorkflowSetupGroupCard.vue:73">
P2: Use an interactive control (e.g. `button`) for the section toggle instead of a clickable `div` so it is keyboard-accessible and has correct semantics.</violation>
</file>

<file name="packages/@n8n/instance-ai/src/tools/workflows/setup-workflow.service.ts">

<violation number="1" location="packages/@n8n/instance-ai/src/tools/workflows/setup-workflow.service.ts:876">
P2: Parent ownership ranking is based on filtered setup requests, so root parents without cards lose execution-order priority and sub-nodes can be grouped under the wrong parent.</violation>
</file>

<file name="packages/testing/playwright/tests/e2e/instance-ai/instance-ai-workflow-setup.spec.ts">

<violation number="1" location="packages/testing/playwright/tests/e2e/instance-ai/instance-ai-workflow-setup.spec.ts:885">
P2: Create the alphabetically first credential first here, or update the expectation to match the actual dropdown order.</violation>
</file>
Architecture diagram
sequenceDiagram
    participant AI as Instance AI Agent
    participant Backend as Backend API
    participant Tool as Workflows Tool
    participant Service as Setup Workflow Service
    participant Frontend as Wizard UI
    participant Sections as useWorkflowSetupSections
    participant Steps as useWorkflowSetupSteps
    participant Wizard as WorkflowSetupWizard
    participant GroupCard as WorkflowSetupGroupCard
    participant SectionCard as WorkflowSetupSectionBody

    Note over AI,Service: NEW: Grouping and Parent/Sub-node support

    AI->>Tool: setup(workflowId)

    Tool->>Service: analyzeWorkflow(workflowId)
    Service->>Service: NEW: filter(isActionableSetupRequest)
    alt No actionable requests
        Tool-->>AI: { success: true, reason: "No nodes require setup." }
    end

    Service->>Service: NEW: buildSubnodeToRootParentMap()
    Note over Service: Walks workflow graph via ALL_NON_MAIN connections
    Service->>Service: Stamp parentNode on sub-node setup requests
    Service-->>Tool: setupRequests[] with parentNode metadata

    Tool-->>AI: suspend with actionable setupRequests
    Note over AI,Tool: NEW: Non-actionable requests filtered out before suspend

    AI-->>Frontend: Open setup wizard with setupRequests

    Frontend->>Sections: useWorkflowSetupSections(setupRequests)
    Sections->>Sections: NEW: Group cred-only requests by credentialType
    Sections->>Sections: NEW: Group HTTP requests by same URL (split expressions)
    Sections->>Sections: NEW: Keep params-bearing requests independent
    Sections-->>Frontend: sections[]

    Frontend->>Steps: useWorkflowSetupSteps({ sections, setupRequests })
    Steps->>Steps: NEW: Fold sections sharing a parentNode into a { group } step
    alt Section has parentNode metadata
        Steps->>Steps: Add to group.subnodeSections
    else Section is itself a parent (has sub-node children)
        Steps->>Steps: Add as group.parentSection
    else No parent
        Steps->>Steps: Emit as { kind: 'section' }
    end
    Steps-->>Frontend: steps[]

    Frontend->>Wizard: Render steps
    Note over Wizard: NEW: Steps can be 'section' or 'group'

    alt Step is kind: 'group'
        Wizard->>GroupCard: render(group)
        GroupCard->>GroupCard: NEW: Show parent header (always visible)
        alt Group has parentSection
            GroupCard->>SectionCard: Render parent inline (no collapse)
        end
        loop For each sub-node section
            GroupCard->>GroupCard: NEW: Collapsible sub-node sections
            GroupCard->>SectionCard: Render with expand/collapse
            Note over GroupCard: Auto-expand first incomplete sub-node
            Note over GroupCard: Auto-collapse completed cred-only sections
        end
    else Step is kind: 'section'
        Wizard->>SectionCard: render(section)
    end
Loading

Note: This PR contains a large number of files. cubic only reviews up to 75 files per PR, so some files may not have been reviewed. cubic prioritizes the most important files to review.
On a pro plan you can use ultrareview for larger PRs.
Fix all with cubic.

const subnodeToRootParent = buildSubnodeToRootParentMap(
workflowJson.nodes,
workflowJson.connections as unknown as IConnections,
setupRequests.map((req) => req.node.name),
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot May 5, 2026

Choose a reason for hiding this comment

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

P2: Parent ownership ranking is based on filtered setup requests, so root parents without cards lose execution-order priority and sub-nodes can be grouped under the wrong parent.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/@n8n/instance-ai/src/tools/workflows/setup-workflow.service.ts, line 876:

<comment>Parent ownership ranking is based on filtered setup requests, so root parents without cards lose execution-order priority and sub-nodes can be grouped under the wrong parent.</comment>

<file context>
@@ -785,5 +866,23 @@ export async function analyzeWorkflow(
+	const subnodeToRootParent = buildSubnodeToRootParentMap(
+		workflowJson.nodes,
+		workflowJson.connections as unknown as IConnections,
+		setupRequests.map((req) => req.node.name),
+	);
+	if (subnodeToRootParent.size > 0) {
</file context>
Fix with Cubic

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Since we're not executing nodes in the instance-ai setup flow, it's fine (or even better) to show the subnode as part of the parent which is actionable since that will result in fewer cards and it still make sense to the user.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the feedback! I've saved this as a new learning to improve future reviews.

Comment on lines +885 to 899
const firstCrdentialInList = await n8n.api.credentials.createCredential({
name: SELECT_EXISTING_TARGET_CREDENTIAL_NAME,
type: 'slackApi',
data: {
accessToken: 'xoxb-initial-token-for-testing',
accessToken: 'xoxb-target-token-for-testing',
},
});
const targetCredential = await n8n.api.credentials.createCredential({
name: SELECT_EXISTING_TARGET_CREDENTIAL_NAME,
const secondCrdentialInList = await n8n.api.credentials.createCredential({
name: SELECT_EXISTING_INITIAL_CREDENTIAL_NAME,
type: 'slackApi',
data: {
accessToken: 'xoxb-target-token-for-testing',
accessToken: 'xoxb-initial-token-for-testing',
},
});

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot May 5, 2026

Choose a reason for hiding this comment

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

P2: Create the alphabetically first credential first here, or update the expectation to match the actual dropdown order.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/testing/playwright/tests/e2e/instance-ai/instance-ai-workflow-setup.spec.ts, line 885:

<comment>Create the alphabetically first credential first here, or update the expectation to match the actual dropdown order.</comment>

<file context>
@@ -576,26 +881,24 @@ test.describe(
-			const initialCredential = await n8n.api.credentials.createCredential({
-				name: SELECT_EXISTING_INITIAL_CREDENTIAL_NAME,
+			// creds are sorted by name, in the dropdown
+			const firstCrdentialInList = await n8n.api.credentials.createCredential({
+				name: SELECT_EXISTING_TARGET_CREDENTIAL_NAME,
 				type: 'slackApi',
</file context>
Suggested change
const firstCrdentialInList = await n8n.api.credentials.createCredential({
name: SELECT_EXISTING_TARGET_CREDENTIAL_NAME,
type: 'slackApi',
data: {
accessToken: 'xoxb-initial-token-for-testing',
accessToken: 'xoxb-target-token-for-testing',
},
});
const targetCredential = await n8n.api.credentials.createCredential({
name: SELECT_EXISTING_TARGET_CREDENTIAL_NAME,
const secondCrdentialInList = await n8n.api.credentials.createCredential({
name: SELECT_EXISTING_INITIAL_CREDENTIAL_NAME,
type: 'slackApi',
data: {
accessToken: 'xoxb-target-token-for-testing',
accessToken: 'xoxb-initial-token-for-testing',
},
});
// creds are sorted by name, in the dropdown
const firstCrdentialInList = await n8n.api.credentials.createCredential({
name: SELECT_EXISTING_INITIAL_CREDENTIAL_NAME,
type: 'slackApi',
data: {
accessToken: 'xoxb-initial-token-for-testing',
},
});
const secondCrdentialInList = await n8n.api.credentials.createCredential({
name: SELECT_EXISTING_TARGET_CREDENTIAL_NAME,
type: 'slackApi',
data: {
accessToken: 'xoxb-target-token-for-testing',
},
});
Fix with Cubic

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

Instance AI Workflow Eval Results

14/14 built | 3 run(s) | pass@3: 74% | pass^3: 43% | iterations: 57% / 60% / 51%

Workflow Build pass@3 pass^3
Every hour, fetch all records from an Airtable table. Use the HTTP Req 3/3 100% 100%
Create a workflow that handles contact form submissions via a webhook. 3/3 60% 60%
Get all the Linear issues created in the last 2 weeks. Filter them for 3/3 100% 14%
Every day, get the posts made in the past day on 3 different Slack cha 3/3 60% 7%
Create a form that collects: name, email, company, and interest level 3/3 100% 100%
Every day, fetch all open GitHub issues from repository 'acme-corp/bac 3/3 100% 29%
Every two weeks I want to check the amount of n8n usage and bug report 2/3 0% 0%
Create a workflow that receives webhook notifications with a JSON body 3/3 100% 100%
Fetch the latest posts from the JSONPlaceholder API (GET https://jsonp 3/3 33% 33%
Every day, fetch one post from the JSONPlaceholder API (GET https://js 3/3 100% 100%
Build a Telegram chatbot workflow for a family assistant. It should re 3/3 0% 0%
Every day at 8am, check the weather in Berlin using the OpenMeteo API 3/3 100% 64%
Every hour, check the current weather for London, New York, and Tokyo 3/3 50% 1%
I want you to build a workflow that will read n8n workflow databases a 3/3 100% 29%
Failure details

Create a workflow that handles contact form submissions via a webhook. / partial-action-failure — 0/3 passed

Run [builder_issue]: The workflow crashed when the Telegram node failed. The connections show all four action nodes (Respond 200 OK, Send Auto-Reply Email, Notify Team via Telegram, Append to Google Sheets) are connected
Run [builder_issue]: The workflow crashed due to the Telegram node error ('Bad request - please check your parameters'), and the 'Append to Google Sheet' node did not run as a result. The three actions (Gmail, Telegram, G
Run [builder_issue]: The workflow crashed entirely when the Telegram node failed. The connections show all three action nodes (Send Auto-Reply Email, Notify Team via Telegram, Append to Google Sheets) are wired in paralle

Create a workflow that handles contact form submissions via a webhook. / invalid-email — 0/3 passed

Run [builder_issue]: The workflow crashed at the 'Send Auto-Reply Email' node with 'Invalid email address (item 0)' because 'not-an-email' is not a valid email. This caused the entire workflow execution to fail — 'Notify
Run [builder_issue]: The workflow crashed entirely at the 'Send Auto-Reply Email' node with the error 'Invalid email address (item 0)'. This caused 'Notify Team on Telegram' and 'Append to Google Sheet' to never execute.
Run [builder_issue]: The workflow crashed entirely when the Gmail node encountered the invalid email address 'not-an-email'. The error 'Invalid email address (item 0)' propagated as a workflow-level error, halting executi

Get all the Linear issues created in the last 2 weeks. Filter them for / happy-path — 1/3 passed

Run [builder_issue]: The workflow executed without errors and posted to Slack successfully. However, several key criteria in the checklist are not met:

  1. 2-week filter not applied: The Build GraphQL Query node hardc

Run [builder_issue]: The workflow fails at the 'Post to Slack' node with an 'invalid syntax' error. The node's 'text' parameter uses an n8n expression containing multi-line JavaScript with const declarations, if statement

Get all the Linear issues created in the last 2 weeks. Filter them for / multi-team-creator — 2/3 passed

Run [builder_issue]: The Process Cross-Team Issues node correctly computed the cross-team summary: Alice's AI issue (ENG-103) was excluded (AI is one of her teams), her 2 Backend issues were counted as cross-team, Bob's F

Get all the Linear issues created in the last 2 weeks. Filter them for / no-cross-team-issues — 1/3 passed

Run [mock_issue]: The scenario requires that Alice maps to 'Frontend' and Bob maps to 'Backend', so all 4 issues match their creators' teams and the cross-team filter should produce 0 results. However, the Team Members
Run [builder_issue]: The workflow errored at the 'Post to Slack' node with 'invalid syntax'. The error is in the node's 'text' parameter, which uses a multi-line JavaScript expression inside an n8n expression field (={{ .

Get all the Linear issues created in the last 2 weeks. Filter them for / unknown-creator — 2/3 passed

Run [builder_issue]: The workflow crashed at the 'Post to Slack' node with an 'invalid syntax' error. The root cause is that the Slack node's 'text' parameter contains a multi-line JavaScript block wrapped in an n8n expre

Get all the Linear issues created in the last 2 weeks. Filter them for / api-error — 1/3 passed

Run [builder_issue]: The workflow crashed with 'Authorization failed - please check your credentials' when the Linear API returned an authentication error. There is no error handling branch (no error trigger node, no try/
Run [builder_issue]: The workflow does not handle the API authentication error gracefully. When Fetch Linear Issues returns an error response (HTTP 200 with an errors array and data: null), the Process Cross-Team Issu

Every day, get the posts made in the past day on 3 different Slack cha / happy-path — 2/3 passed

Run [builder_issue]: The workflow failed at the 'Build Prompt' node with an 'invalid syntax' error. The node's value expression contains a multi-line JavaScript block using const, let, for...of, and return stateme

Every day, get the posts made in the past day on 3 different Slack cha / empty-channel — 1/3 passed

Run [builder_issue]: The workflow failed at the 'Build Prompt' node with an 'invalid syntax' error. The node uses a JavaScript expression in a Set node that contains a for...of loop and multi-line logic. In n8n's expres
Run [mock_issue]: The workflow failed with an error at 'Fetch #engineering': 'Cannot read properties of undefined (reading 'matches')'. This error occurred because the mock response for Fetch #engineering returned an e

Every day, get the posts made in the past day on 3 different Slack cha / high-volume — 1/3 passed

Run [builder_issue]: The workflow executed successfully through the merge and aggregation steps — all 4–5 messages per channel were correctly fetched, aggregated, labelled, merged across three channels, and re-aggregated
Run [builder_issue]: The workflow executed without errors and the summary was posted successfully to #daily-digest. However, data was lost in the merge step. The Merge channels node is configured with mode='combine' and c

Every day, get the posts made in the past day on 3 different Slack cha / channel-not-found — 0/3 passed

Run [builder_issue]: The workflow has no error handling for the 'Fetch #product' node failure. When the mock returned {ok: false, error: 'channel_not_found'}, the Slack node threw an error ('Slack error response: channel_
Run [builder_issue]: The workflow does not handle the channel-not-found error gracefully. When 'Fetch #product' received a 404 response (mock returned {ok: false, error: 'channel_not_found'}), the Slack node threw 'Reques
Run [builder_issue]: The workflow crashes entirely when Fetch #product returns a channel_not_found error. There is no error handling (e.g., no 'Continue on Error' setting, no try/catch, no IF node to handle Slack errors)

Every day, get the posts made in the past day on 3 different Slack cha / insufficient-permissions — 0/3 passed

Run [builder_issue]: The workflow crashed when Fetch #product returned a 403 error (mock response had ok:false with 'not_in_channel'). The workflow has no error handling configured on the Fetch #product node (no 'Continue
Run [builder_issue]: The workflow crashed when Fetch #product returned a 'not_in_channel' error. No error handling exists in the workflow — there is no error branch, no continue-on-error setting, and no fallback path for
Run [builder_issue]: The workflow crashed entirely when 'Fetch #product' returned a 'not_in_channel' Slack error. The error propagated up and halted the entire workflow execution. No error handling (try/catch, error branc

Every day, fetch all open GitHub issues from repository 'acme-corp/bac / happy-path — 2/3 passed

Run [builder_issue]: The workflow errored with 'Cannot read properties of undefined (reading 'type')' in the Create Notion Page node. The mock response for the POST to https://api.notion.com/v1/pages returned only {object

Every day, fetch all open GitHub issues from repository 'acme-corp/bac / no-bugs — 2/3 passed

Run [verification_failure]: No verification result — LLM verifier returned empty

Every two weeks I want to check the amount of n8n usage and bug report / happy-path — 0/3 passed

Run [build_failure]: Build failed: Agent response: No credentials for Linear, BigQuery, or Slack are set up yet. I'll note these as needing setup. Let me now check for relevant nodes.Good — native Linear and BigQuery node
Run [builder_issue]: The workflow failed to execute. The pre-analysis flags a builder issue: 'BigQuery - Usage Stats' has a missing/invalid configuration — the projectId is set to a placeholder value '<__PLACEHOLDER_VALUE
Run [builder_issue]: The workflow failed to execute. The BigQuery - Execution Stats node has a misconfigured projectId set to a placeholder value '<PLACEHOLDER_VALUE__BigQuery Project ID>' which is not a valid BigQuer

Fetch the latest posts from the JSONPlaceholder API (GET https://jsonp / happy-path — 0/3 passed

Run [builder_issue]: The workflow executed without errors and the Slack message was posted to #api-digest. However, the Filter Out 'qui' Titles node did not correctly filter all posts containing 'qui'. Its output includes
Run [.]: The workflow executed without errors and the Slack message was posted to #api-digest with a count of remaining posts and their titles. However, the Filter Out qui node failed to properly filter all po
Run [builder_issue]: The workflow did not complete successfully. Only Manual Trigger, Fetch Posts, and Split Posts executed. Filter Out 'qui', Aggregate Titles, Build Message, and Send to Slack all did not run. The root c

Fetch the latest posts from the JSONPlaceholder API (GET https://jsonp / all-filtered — 0/3 passed

Run [builder_issue]: The Filter Out 'qui' Titles node was configured with a 'notContains' condition to filter out posts whose titles contain 'qui', but its output shows all 3 posts passed through — including titles 'qui e
Run [builder_issue]: The Filter Out qui node was supposed to filter OUT all posts containing 'qui' in the title, leaving zero items. However, its output shows all 3 posts still passing through — including posts with 'qui'
Run [builder_issue]: The Filter Out 'qui' node was supposed to filter OUT posts whose titles contain 'qui', leaving only posts that do NOT contain 'qui'. In this scenario all 3 posts contain 'qui', so the filter should pr

Build a Telegram chatbot workflow for a family assistant. It should re / distinct-telegram-chat — 0/3 passed

Run [builder_issue]: The workflow executes without errors and correctly sends the reply to chat id 123456 with the AI Agent's answer. However, the checklist specifically requires that the memory node scopes conversation h
Run [builder_issue]: The workflow structure and execution are mostly correct — Telegram Trigger → Family Assistant Agent → Send Reply, with OpenAI GPT-4o and Window Buffer Memory connected as sub-nodes to the agent. The S
Run [builder_issue]: The workflow executes without errors and the final Telegram response is correctly sent to chat id 123456 using the explicit source-node reference $('Telegram Trigger').item.json.message.chat.id. The

Every day at 8am, check the weather in Berlin using the OpenMeteo API / rain-not-expected — 2/3 passed

Run [mock_issue]: The workflow did not execute without errors. The 'Fetch Berlin Forecast' node received a mock generation failure response (_evalMockError), causing the 'Parse Rain Forecast' code node to crash with 'C

Every hour, check the current weather for London, New York, and Tokyo / happy-path — 0/3 passed

Run [mock_issue]: Multiple sub-criteria fail:

  1. New York weather API call did not succeed: The mock for 'Fetch New York Weather' returned a _evalMockError response (mock generation failed with a JSON parse error)

Run [mock_issue]: Multiple criteria failed:

  1. New York weather API mock failed: The 'Fetch New York Weather' node received {_evalMockError: true, message: 'Mock generation failed...'} instead of real weather da

Run [mock_issue]: The workflow failed with 'Invalid or unexpected token' in the Find Hot Cities code node. The root cause is the mock generation failure for Weather - New York: the LLM mock returned a _evalMockError re

Every hour, check the current weather for London, New York, and Tokyo / no-alerts — 1/3 passed

Run [builder_issue]: The workflow executed without errors and correctly routed to the cool branch (no Telegram alert sent). However, only 1 of the 3 city readings was logged to Airtable. The Aggregate All Cities node rece
Run [builder_issue]: The workflow failed with 'Invalid or unexpected token' in the Find Hot Cities code node. The root cause is a mock issue: the Weather - New York mock generation failed (returned _evalMockError), which

I want you to build a workflow that will read n8n workflow databases a / happy-path — 2/3 passed

Run [builder_issue]: The workflow executed without errors up through the 'Check Existing Row' node, which returned no output. As a result, the 'Row Exists?' IF node, 'Update Row', and 'Insert Row' nodes did not execute. T

@scdekov scdekov changed the title Feature/instance ai workflow setup rewrite pr4 Instance AI workflow setup nodes groupping May 5, 2026
@scdekov scdekov requested a review from CharlieKolb May 5, 2026 13:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

n8n team Authored by the n8n team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant