Skip to content

fix(ai-builder): Handle data table name conflict gracefully instead of looping (no-changelog)#28279

Open
JoseBra wants to merge 3 commits intomasterfrom
ai-2358-bug-data-table-name-conflict-causes-builder-to-loop-and
Open

fix(ai-builder): Handle data table name conflict gracefully instead of looping (no-changelog)#28279
JoseBra wants to merge 3 commits intomasterfrom
ai-2358-bug-data-table-name-conflict-causes-builder-to-loop-and

Conversation

@JoseBra
Copy link
Copy Markdown
Contributor

@JoseBra JoseBra commented Apr 10, 2026

Summary

  • Fix create-data-table tool throwing DataTableNameConflictError when the table already exists during the builder's rebuild cycle, causing the agent to waste iterations retrying
  • Return denied: true with guidance to use the existing table, which the agent handles gracefully
  • Add unit tests for the create-data-table tool (8 tests covering all tool states)

Before / After

Before After
Build 1/3 succeeded (parallel runs) 3/3 succeeded

Context

Reported independently by product team — a user spent 45 min trying to build a workflow with a data table before giving up. The data table conflict during the builder's rebuild cycle wastes agent iterations and context, making it more likely to hit proxy timeouts.

Related Linear ticket

https://linear.app/n8n/issue/AI-2358

Review checklist

  • I have seen this code, I have run this code, and I take responsibility for this code.

Test plan

  • Unit tests: 8/8 passing (create, conflict handling, suspension, permission blocked, non-conflict errors)
  • Typecheck clean
  • Manual before/after testing: without fix 1/3 builds succeed, with fix 3/3 builds succeed

🤖 Generated with Claude Code

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 10, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@n8n-assistant n8n-assistant bot added the n8n team Authored by the n8n team label Apr 10, 2026
…f looping (no-changelog)

When the builder creates a workflow involving a data table, it creates
the table in run #1 then tries to create it again in run #2 (rebuild
phase). The DataTableNameConflictError causes the agent to retry in a
loop until the build times out.

Fix: catch the conflict error and return `denied: true` with a reason
guiding the agent to use the existing table. The agent already handles
denied responses gracefully.

Before: BUILD FAILED after 175s of looping
After: BUILD SUCCESS in ~3 min, 3/3 scenarios passing

Ref: https://linear.app/n8n/issue/AI-2358

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@JoseBra JoseBra force-pushed the ai-2358-bug-data-table-name-conflict-causes-builder-to-loop-and branch from 0ebd291 to e25246c Compare April 10, 2026 02:03
…no-changelog)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@JoseBra JoseBra marked this pull request as ready for review April 10, 2026 07:47
@JoseBra JoseBra requested review from OlegIvaniv and aalises April 10, 2026 07:47
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.

1 issue found across 2 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/@n8n/instance-ai/src/tools/data-tables/create-data-table.tool.ts">

<violation number="1" location="packages/@n8n/instance-ai/src/tools/data-tables/create-data-table.tool.ts:117">
P1: Convert `DataTableNameConflictError` to `denied: true` unconditionally. The extra `list()` check can still rethrow the conflict and recreate the retry loop described in AI-2358.</violation>
</file>
Architecture diagram
sequenceDiagram
    participant Agent as AI Agent (Mastra)
    participant Tool as Tool: create-data-table
    participant Service as DataTableService
    participant DB as Database

    Note over Agent, DB: Request Flow: Data Table Creation

    Agent->>Tool: execute(name, columns)
    
    alt Permission: require_approval
        Tool->>Agent: suspend(message)
        Note over Agent, Tool: User approves action
        Agent->>Tool: resume(approved: true)
    else Permission: blocked
        Tool-->>Agent: { denied: true, reason: "Action blocked" }
    end

    Note over Tool, Service: Execution Phase (CHANGED)

    Tool->>Service: create(name, columns)
    Service->>DB: INSERT INTO data_tables ...
    
    alt Table Name Unique
        DB-->>Service: Table Record
        Service-->>Tool: table
        Tool-->>Agent: { table }
    else Table Name Conflict
        DB-->>Service: Error (Unique Constraint)
        Service-->>Tool: throw DataTableNameConflictError
        
        Note over Tool: NEW: Handle conflict to prevent retry loop
        
        Tool->>Service: list({ projectId })
        Service->>DB: SELECT * FROM data_tables
        DB-->>Service: existing tables
        Service-->>Tool: tables
        
        opt Table found in list
            Tool-->>Agent: CHANGED: { denied: true, reason: "Table already exists..." }
            Note right of Agent: Agent continues gracefully<br/>instead of retrying
        end
    else Other Error
        Service-->>Tool: throw Error
        Tool-->>Agent: Exception (Agent may retry)
    end
Loading

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

… (no-changelog)

The conflict error already tells us the table exists — no need to
verify with list(). The extra call could fail and re-throw the
original error, defeating the fix.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
*/
function isNameConflictError(error: unknown): boolean {
let current: unknown = error;
while (current instanceof Error) {
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.

That's neat!

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.

2 participants