Skip to content

fix(core): Validate non-empty prompts in AI vendor nodes before API calls (backport to release-candidate/2.21.x)#30820

Merged
alexander-gekov merged 1 commit into
release-candidate/2.21.xfrom
backport-30795-to-release-candidate/2.21.x
May 20, 2026
Merged

fix(core): Validate non-empty prompts in AI vendor nodes before API calls (backport to release-candidate/2.21.x)#30820
alexander-gekov merged 1 commit into
release-candidate/2.21.xfrom
backport-30795-to-release-candidate/2.21.x

Conversation

@n8n-assistant
Copy link
Copy Markdown
Contributor

@n8n-assistant n8n-assistant Bot commented May 20, 2026

Description

Backport of #30795 to release-candidate/2.21.x.

Checklist for the author (@alexander-gekov) 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

AI vendor nodes (Google Gemini, OpenAI, Anthropic) did not validate that user prompts are non-empty before sending requests to upstream APIs. Empty or whitespace-only prompts result in wasted API round-trips (400 errors from providers) and, when routed through the AI Gateway, waste proxy resources without any budget deduction.

This PR adds trim() + empty check with NodeOperationError in each operation's execute() before the API call, ensuring workflows fail fast at the node level with a clear error message.

Changes

Text message operations (Priority 1):

  • Google Gemini: Text > Message
  • OpenAI v1: Text > Message
  • OpenAI v2: Text > Response
  • Anthropic: Text > Message

Generation operations (Priority 2):

  • Google Gemini: Image > Generate, Image > Edit, Video > Generate
  • OpenAI v1/v2: Image > Generate, Video > Generate (v2)

Analyze operations (Priority 3):

  • Google Gemini: all analyze ops via shared baseAnalyze.ts
  • Anthropic: image/document analyze via shared baseAnalyze.ts
  • OpenAI v1/v2: Image > Analyze

How to test

  1. Use any of the affected nodes (e.g. Google Gemini Text > Message)
  2. Leave the prompt empty or set to whitespace only
  3. Execute the workflow
  4. Verify the node throws a NodeOperationError with message "A non-empty prompt is required." instead of making an API call

Related Linear tickets, Github issues, and Community forum posts

https://linear.app/n8n/issue/NODE-5096

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)

🤖 PR Summary generated by AI

Made with Cursor

…alls (#30795)

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Michael Kret <88898367+michael-radency@users.noreply.github.com>
(cherry picked from commit d8ef975)
@codecov
Copy link
Copy Markdown

codecov Bot commented May 20, 2026

Bundle Report

Changes will decrease total bundle size by 8.44kB (-0.02%) ⬇️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
editor-ui-esm 46.22MB -8.44kB (-0.02%) ⬇️

Affected Assets, Files, and Routes:

view changes for bundle: editor-ui-esm

Assets Changed:

Asset Name Size Change Total Size Change (%)
assets/typescript.worker-*.js 66 bytes 10.87MB 0.0%
assets/worker-*.js 3.14MB 3.16MB 17553.32% ⚠️
assets/worker-*.js -3.14MB 17.9kB -99.43%
assets/constants-*.js 156 bytes 3.15MB 0.0%
assets/core-*.js -85 bytes 662.93kB -0.01%
assets/InstanceAiThreadView-*.js 138 bytes 318.62kB 0.04%
assets/AppSidebar-*.js -4.79kB 35.28kB -11.96%
assets/AppSidebar-*.css -3.2kB 12.85kB -19.95%
assets/resourceCenter.store-*.js -790 bytes 4.62kB -14.6%

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 22 files

Architecture diagram
sequenceDiagram
    participant WF as Workflow Engine
    participant NV as AI Vendor Node
    participant PV as Prompt Validator
    participant API as Upstream AI API

    Note over WF,API: NEW: Prompt validation before external API calls

    WF->>NV: execute(i)
    NV->>NV: Extract node parameters (modelId, prompt/text, options, etc.)

    alt Text/Message Operations (Anthropic, Gemini, OpenAI v1/v2)
        NV->>PV: validateMessages(messages, addAttachments)
        PV->>PV: Filter out empty/whitespace-only messages
        alt No non-empty messages AND no attachments
            PV-->>NV: throw NodeOperationError("A non-empty prompt is required.")
        else Has valid content
            PV-->>NV: Return filtered messages
        end
    else Image/Video Generate Operations (all vendors)
        NV->>PV: validatePrompt(prompt)
        PV->>PV: Check prompt.trim() is non-empty
        alt Prompt empty or whitespace-only
            PV-->>NV: throw NodeOperationError("A non-empty prompt is required.")
        else Valid prompt
            PV-->>NV: Continue
        end
    else Analyze Operations (all vendors via baseAnalyze.ts)
        NV->>PV: validateText(text)
        PV->>PV: Check text.trim() is non-empty
        alt Text empty or whitespace-only
            PV-->>NV: throw NodeOperationError("A non-empty prompt is required.")
        else Valid text
            PV-->>NV: Continue
        end
    end

    alt Validation PASSED
        NV->>API: Make AI provider request (HTTP/HTTPS)
        API-->>NV: Return AI response (success/error)
        NV-->>WF: Return execution data
    else Validation FAILED
        NV-->>WF: NodeOperationError with itemIndex
        Note over WF: Workflow fails fast at node level<br/>No API call made, no resource waste
    end

    Note over NV,PV: Special case: Anthropic allows empty messages when attachments are present
Loading

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

@codecov
Copy link
Copy Markdown

codecov Bot commented May 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@github-actions
Copy link
Copy Markdown
Contributor

Performance Comparison

Comparing currentlatest master14-day baseline

docker-stats

Metric Current Latest Master Baseline (avg) vs Master vs Baseline Status
docker-image-size-n8n 1382.40 MB 1607.68 MB 1457.20 MB (σ 110.39) -14.0% -5.1%
docker-image-size-runners 388.00 MB 405.00 MB 400.04 MB (σ 9.80) -4.2% -3.0% ⚠️

Idle baseline with Instance AI module loaded

Metric Current Latest Master Baseline (avg) vs Master vs Baseline Status
instance-ai-heap-used-baseline 159.68 MB 159.68 MB 197.62 MB (σ 13.32) +0.0% -19.2% 🔴
instance-ai-rss-baseline 338.31 MB 338.31 MB 384.86 MB (σ 31.56) +0.0% -12.1% ⚠️

Memory consumption baseline with starter plan resources

Metric Current Latest Master Baseline (avg) vs Master vs Baseline Status
memory-heap-used-baseline 130.40 MB 130.40 MB 124.49 MB (σ 3.14) +0.0% +4.7% ⚠️
memory-rss-baseline 389.10 MB 389.10 MB 299.43 MB (σ 37.75) +0.0% +29.9% 🔴
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

@alexander-gekov alexander-gekov merged commit 15d0dbb into release-candidate/2.21.x May 20, 2026
55 checks passed
@alexander-gekov alexander-gekov deleted the backport-30795-to-release-candidate/2.21.x branch May 20, 2026 13:44
This was referenced May 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant