Skip to content

feat: Add min_length/max_length support for String inputs#12543

Open
bigcat88 wants to merge 5 commits intomasterfrom
feat/string-min-max-length
Open

feat: Add min_length/max_length support for String inputs#12543
bigcat88 wants to merge 5 commits intomasterfrom
feat/string-min-max-length

Conversation

@bigcat88
Copy link
Copy Markdown
Contributor

@bigcat88 bigcat88 commented Feb 20, 2026

  • Add min_length and max_length parameters to IO.String.Input, mirroring how min/max work for Int/Float inputs
  • Validation runs in two places in execution.py:
    • First, in validate_inputs() for direct widget values - this is the same pre-execution validation step where int min/max are already checked, so the user gets a clear error before execution starts.
    • Second, in a new validate_resolved_inputs() function that runs right before execute(). This is needed because when a string value comes from an upstream node via a link, it's not known during validate_inputs() since the upstream node hasn't run yet. Without this second check, linked string values would bypass length validation entirely.
Details Screenshot From 2026-02-20 16-41-06 Screenshot From 2026-02-20 16-43-07 Screenshot From 2026-02-20 16-43-48

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 20, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

String.Input gained optional min_length and max_length parameters, stored as self.min_length/self.max_length and included as minLength/maxLength in as_dict. Input validation was extended: validate_inputs now checks STRING-specific length constraints, and a new validate_resolved_inputs(input_data_all, class_def, inputs) function was added and invoked after input resolution to enforce minLength/maxLength, raising ValueError on violations.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.90% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main feature added: min_length/max_length support for String inputs, matching the core objective of the changeset.
Description check ✅ Passed The description comprehensively explains the feature, validation implementation details, and includes screenshots demonstrating the functionality.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
comfy_api_nodes/nodes_recraft.py (1)

884-922: ⚠️ Potential issue | 🟡 Minor

RecraftReplaceBackgroundNode.prompt missing max_length=1000

All other Recraft V3 nodes using RecraftImageGenerationRequest (RecraftTextToImageNode, RecraftImageToImageNode, RecraftImageInpaintingNode, RecraftTextToVectorNode) were updated with max_length=1000 in this PR. RecraftReplaceBackgroundNode.prompt (line 890) was skipped, leaving it without a schema-level upper-bound. Over-limit prompts will pass schema validation and only fail at the Recraft API, producing a less user-friendly error.

🛠️ Proposed fix
-                IO.String.Input("prompt", tooltip="Prompt for the image generation.", default="", multiline=True),
+                IO.String.Input("prompt", tooltip="Prompt for the image generation.", default="", multiline=True, max_length=1000),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@comfy_api_nodes/nodes_recraft.py` around lines 884 - 922, The prompt field
for RecraftReplaceBackgroundNode lacks the schema upper bound; update the
IO.String.Input call for "prompt" in the RecraftReplaceBackgroundNode definition
to include max_length=1000 (matching other Recraft V3 nodes using
RecraftImageGenerationRequest) so the input declaration enforces the same
1000-character limit at schema level.
comfy_api_nodes/nodes_kling.py (1)

2308-2314: ⚠️ Potential issue | 🟡 Minor

KlingLipSyncTextToVideoNode.text should also have min_length=1

max_length=120 was added correctly, but no min_length=1 was set. The node always operates in "text2video" mode (line 2362) where text content is required by the Kling API. There is no runtime guard: an empty text input will pass schema validation and reach the API, which will reject it with an opaque error.

🛠️ Proposed fix
                 IO.String.Input(
                     "text",
                     multiline=True,
                     max_length=120,
+                    min_length=1,
                     tooltip="Text Content for Lip-Sync Video Generation. Required when mode is text2video.",
                 ),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@comfy_api_nodes/nodes_kling.py` around lines 2308 - 2314, The text input for
KlingLipSyncTextToVideoNode is missing a minimum length constraint, so an empty
string can pass validation and reach the Kling API; update the IO.String.Input
for the "text" field (in KlingLipSyncTextToVideoNode) to include min_length=1
alongside the existing max_length=120 and multiline/tooltip settings so the
schema enforces a non-empty value before calling the API.
🧹 Nitpick comments (2)
comfy_api_nodes/nodes_kling.py (1)

85-107: Partial migration: storyboard prompts lack min_length=1 in schema

_generate_storyboard_inputs now enforces max_length=512 at the schema level, but does not set min_length=1. All four callers of this function (OmniProTextToVideoNode, OmniProFirstLastFrameNode, OmniProImageToVideoNode, KlingVideoNode) retain validate_string(sb_prompt, ..., min_length=1, max_length=512) in their execute loops. Adding min_length=1 here would complete the migration and allow those runtime calls to be removed.

♻️ Proposed refactor
         IO.String.Input(
             f"storyboard_{i}_prompt",
             multiline=True,
             default="",
             max_length=512,
+            min_length=1,
             tooltip=f"Prompt for storyboard segment {i}.",
         ),

After this change, the validate_string(sb_prompt, field_name=f"storyboard_{i}_prompt", min_length=1, max_length=512) calls in each execute method can be removed.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@comfy_api_nodes/nodes_kling.py` around lines 85 - 107, The schema for
storyboard prompts in _generate_storyboard_inputs sets max_length=512 but misses
min_length=1; update the IO.String.Input call inside _generate_storyboard_inputs
to include min_length=1 so the field-level validation mirrors the runtime
checks, and then remove the now-redundant validate_string(..., min_length=1,
max_length=512) calls from the execute methods of OmniProTextToVideoNode,
OmniProFirstLastFrameNode, OmniProImageToVideoNode and KlingVideoNode.
comfy_api_nodes/nodes_recraft.py (1)

304-324: RecraftStyleInfiniteStyleLibrary still uses runtime validation instead of schema-level min_length

The PR migrates all other nodes to schema-level constraints, but style_id retains its runtime if not style_id: raise Exception(...) guard (line 322) while the schema input (line 313) has no min_length=1. This is inconsistent with the pattern established by this PR.

♻️ Proposed refactor
-                IO.String.Input("style_id", default="", tooltip="UUID of style from Infinite Style Library."),
+                IO.String.Input("style_id", default="", tooltip="UUID of style from Infinite Style Library.", min_length=1),
     `@classmethod`
     def execute(cls, style_id: str) -> IO.NodeOutput:
-        if not style_id:
-            raise Exception("The style_id input cannot be empty.")
-        return IO.NodeOutput(RecraftStyle(style_id=style_id))
+        return IO.NodeOutput(RecraftStyle(style_id=style_id))
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@comfy_api_nodes/nodes_recraft.py` around lines 304 - 324, The node
RecraftStyleInfiniteStyleLibrary currently performs runtime validation in
execute (if not style_id ...) while its schema Input for "style_id" lacks a
min_length; update the schema in define_schema to use
IO.String.Input("style_id", default="", tooltip="...", min_length=1) and remove
the runtime guard from execute so validation is handled at schema level; leave
the rest of the function returning
IO.NodeOutput(RecraftStyle(style_id=style_id)) unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@comfy_api_nodes/nodes_kling.py`:
- Around line 2444-2445: The schema for KlingImageGenerationNode currently sets
the negative_prompt IO.String.Input max_length to 500 but the module defines
MAX_NEGATIVE_PROMPT_LENGTH_IMAGE_GEN = 200 and the node's execute method no
longer validates strings, causing API rejection for negatives >200 chars; update
the IO.String.Input for "negative_prompt" inside KlingImageGenerationNode to use
max_length=MAX_NEGATIVE_PROMPT_LENGTH_IMAGE_GEN (200) so the schema matches the
intended limit and prevents invalid inputs from reaching the Kling API.

---

Outside diff comments:
In `@comfy_api_nodes/nodes_kling.py`:
- Around line 2308-2314: The text input for KlingLipSyncTextToVideoNode is
missing a minimum length constraint, so an empty string can pass validation and
reach the Kling API; update the IO.String.Input for the "text" field (in
KlingLipSyncTextToVideoNode) to include min_length=1 alongside the existing
max_length=120 and multiline/tooltip settings so the schema enforces a non-empty
value before calling the API.

In `@comfy_api_nodes/nodes_recraft.py`:
- Around line 884-922: The prompt field for RecraftReplaceBackgroundNode lacks
the schema upper bound; update the IO.String.Input call for "prompt" in the
RecraftReplaceBackgroundNode definition to include max_length=1000 (matching
other Recraft V3 nodes using RecraftImageGenerationRequest) so the input
declaration enforces the same 1000-character limit at schema level.

---

Nitpick comments:
In `@comfy_api_nodes/nodes_kling.py`:
- Around line 85-107: The schema for storyboard prompts in
_generate_storyboard_inputs sets max_length=512 but misses min_length=1; update
the IO.String.Input call inside _generate_storyboard_inputs to include
min_length=1 so the field-level validation mirrors the runtime checks, and then
remove the now-redundant validate_string(..., min_length=1, max_length=512)
calls from the execute methods of OmniProTextToVideoNode,
OmniProFirstLastFrameNode, OmniProImageToVideoNode and KlingVideoNode.

In `@comfy_api_nodes/nodes_recraft.py`:
- Around line 304-324: The node RecraftStyleInfiniteStyleLibrary currently
performs runtime validation in execute (if not style_id ...) while its schema
Input for "style_id" lacks a min_length; update the schema in define_schema to
use IO.String.Input("style_id", default="", tooltip="...", min_length=1) and
remove the runtime guard from execute so validation is handled at schema level;
leave the rest of the function returning
IO.NodeOutput(RecraftStyle(style_id=style_id)) unchanged.

Comment thread comfy_api_nodes/nodes_kling.py Outdated
@Kosinkadink
Copy link
Copy Markdown
Member

Can you separate this into two PRs? The first would just add min_length and max_length to the schema. The second would make the API node changes

@comfy-pr-bot
Copy link
Copy Markdown
Member

Test Evidence Check

@bigcat88 bigcat88 force-pushed the feat/string-min-max-length branch from 2fc7012 to ad327d5 Compare February 28, 2026 16:01
@bigcat88 bigcat88 marked this pull request as draft March 2, 2026 06:44
@bigcat88 bigcat88 force-pushed the feat/string-min-max-length branch 2 times, most recently from 75364cb to 2500d0f Compare March 2, 2026 13:14
@bigcat88 bigcat88 marked this pull request as ready for review March 2, 2026 13:44
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@comfy_api/latest/_io.py`:
- Around line 327-330: The __init__ signature change inserted min_length and
max_length before existing tail args causing a positional-argument break for
callers of String.Input; restore backward compatibility by moving the new
parameters (min_length, max_length) to the end of the parameter list (after
socketless, force_input, extra_dict, raw_link, advanced) in the __init__
definition for the relevant class/function (the __init__ shown in
comfy_api/latest/_io.py), so existing positional calls keep their original
bindings while still exposing the new optional arguments.

In `@execution.py`:
- Around line 218-252: The validate_resolved_inputs function currently validates
all STRING entries in input_data_all (in validate_resolved_inputs), which causes
direct widget values to be re-validated here; change it to only validate values
that originated from resolved links: detect the same "rawLink" / linked-input
marker used by get_input_data() and skip entries that are not links so direct
widget inputs remain governed by validate_inputs()/VALIDATE_INPUTS; keep
existing MIN/MAX length checks and error messages but only run them for inputs
flagged as resolved links (use the same rawLink metadata/key and preserve the
is_v3/_io finalization logic and get_input_info lookups).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 4d467d38-ec16-4b46-9cd5-53f6c453f922

📥 Commits

Reviewing files that changed from the base of the PR and between 2500d0f and e68dc1e.

📒 Files selected for processing (2)
  • comfy_api/latest/_io.py
  • execution.py

Comment thread comfy_api/latest/_io.py Outdated
Comment thread execution.py Outdated
@bigcat88 bigcat88 force-pushed the feat/string-min-max-length branch from e68dc1e to de75f50 Compare March 9, 2026 06:25
@bigcat88 bigcat88 force-pushed the feat/string-min-max-length branch from de75f50 to 5b913f0 Compare March 9, 2026 07:06
@bigcat88 bigcat88 added the Core Core team dependency label Mar 11, 2026
Comment thread execution.py
@alexisrolland
Copy link
Copy Markdown
Member

@bigcat88 I see this is causing a lot of discussions and I am not sold to the idea of adding these nodes and additional options. What is the need here? Can we close it?

@bigcat88
Copy link
Copy Markdown
Contributor Author

bigcat88 commented May 5, 2026

@alexisrolland, this PR fell out of our sights

It is actually necessary, and the plan was to add validation for other types in future PRs (audio/video length, image/video size, and so on) so that it would all be declarative and could be declared in the schema

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

Labels

Core Core team dependency

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants