Skip to content

Conversation

@PrathameshJoshi123
Copy link

@PrathameshJoshi123 PrathameshJoshi123 commented Nov 21, 2025

Problem

Requests containing both text and image data (sent as multipart/form-data) while including a session_id caused a server error (IndexError/500). The server incorrectly attempted to parse the request body as pure JSON, which consumed the multipart/form-data stream and led to missing input fields downstream.

Change

The logic in parse_input_request_from_body has been updated to correctly handle different content types:

  • Content-Type Detection: The function now detects the request's Content-Type.
  • Multipart Handling: If the Content-Type is multipart/form-data, it now uses await request.form() to correctly parse the data, extract expected form fields (including session_id), and map them into a SimplifiedAPIRequest.
  • JSON Fallback: The existing logic for handling application/json requests is preserved (no change in behavior for standard JSON requests).
  • Error Handling: Parse failures are logged, and a default SimplifiedAPIRequest is returned on error, maintaining the previous error-handling behavior.

Why This Fixes It

Multipart requests are now parsed correctly via request.form(). This ensures that file streams and form fields (like session_id) are preserved. Downstream processing code no longer encounters an empty inputs list, which was the root cause of the IndexError.

Files Changed

  • (src\backend\base\langflow\api\v1\endpoints.py) — Modified parse_input_request_from_body

Tests

curl.exe -v -X POST "[http://127.0.0.1:7860/run/](http://127.0.0.1:7860/run/)<FLOW_ID_OR_NAME>" \
-F "input_value=hello" \
-F "session_id=test-session-123" \
-F "file=@./test_upload.txt"

Fixes: #9859

Summary by CodeRabbit

Release Notes

  • New Features
    • API endpoint now supports multipart/form-data requests alongside existing JSON support, enabling flexible request submission methods with enhanced form data handling capabilities.

✏️ Tip: You can customize this high-level summary in your review settings.

@github-actions github-actions bot added the community Pull Request from an external contributor label Nov 21, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 21, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

Added multipart/form-data handling to the API request parsing function. The endpoint now detects multipart requests and extracts form fields (input_value, input_type, output_type, output_component, session_id) plus optional JSON-encoded tweaks, while maintaining backward compatibility with JSON body parsing.

Changes

Cohort / File(s) Summary
Multipart Request Parsing
src/backend/base/langflow/api/v1/endpoints.py
Added content-type detection and form data extraction in parse_input_request_from_body. Maps multipart form fields to SimplifiedAPIRequest schema and supports JSON tweaks parsing with fallback handling. Preserves existing JSON fallback for non-multipart requests.

Sequence Diagram

sequenceDiagram
    participant Client
    participant API
    participant Endpoint

    Client->>API: POST request<br/>(multipart or JSON)
    API->>Endpoint: Route to parse_input_request_from_body()
    
    alt Multipart Content-Type
        Endpoint->>Endpoint: Read request.form()
        Endpoint->>Endpoint: Extract form fields<br/>(input_value, session_id, etc.)
        Endpoint->>Endpoint: Parse tweaks field<br/>(JSON decode)
        Endpoint->>Endpoint: Construct SimplifiedAPIRequest
    else JSON Content-Type
        Endpoint->>Endpoint: Parse request body<br/>as JSON (fallback)
        Endpoint->>Endpoint: Construct SimplifiedAPIRequest
    end
    
    Endpoint->>API: Return SimplifiedAPIRequest
    API->>Client: Process request
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Single file modification with localized logic addition
  • Straightforward conditional branching based on content-type
  • Minimal state changes and well-defined responsibility boundaries
  • Consideration: Verify error handling for edge cases (malformed tweaks JSON, missing required form fields, multipart parsing failures)

Pre-merge checks and finishing touches

Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Test Coverage For New Implementations ❌ Error PR modifies parse_input_request_from_body function for multipart/form-data handling and session_id extraction but no new test files were found to verify this critical functionality. Add comprehensive test coverage including unit tests for multipart request parsing, regression tests for issue #9859 (text+image+session_id scenario), JSON-encoded tweaks validation, and error handling tests.
Test Quality And Coverage ⚠️ Warning PR implements substantial async multipart/form-data handling in critical API endpoint but provides no automated test coverage, relying only on manual curl testing. Add pytest-asyncio tests covering multipart/form-data parsing, file uploads, JSON tweaks parsing, session_id extraction, error handling, and regression tests for application/json requests.
Test File Naming And Structure ❓ Inconclusive Test file coverage for parse_input_request_from_body multipart/form-data changes could not be verified due to unclear repository test structure. Confirm test file location and whether new tests covering multipart/form-data handling, session_id extraction, and error scenarios were added to this PR.
✅ Passed checks (6 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding multipart/form-data parsing and session_id extraction for the /run endpoint, with a direct reference to the fixed issue.
Linked Issues check ✅ Passed The PR successfully addresses all coding requirements from issue #9859: multipart/form-data parsing with session_id extraction, preserving JSON handling, robust error handling with logging, and preventing the IndexError that occurred with text+image+session_id combinations.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the parse_input_request_from_body function to handle multipart/form-data requests and extract session_id, with no unrelated modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Excessive Mock Usage Warning ✅ Passed PR modifies only production code in parse_input_request_from_body function; no test files are included or modified in this PR.

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.

@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Nov 21, 2025
@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Nov 21, 2025
Copy link
Contributor

@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

🧹 Nitpick comments (1)
src/backend/base/langflow/api/v1/endpoints.py (1)

84-93: Consider adding type guards for form field extraction.

Form fields can be either strings or UploadFile objects in multipart requests. If a client mistakenly uploads files under field names like input_value or session_id, they would be UploadFile objects, potentially causing Pydantic validation errors when constructing SimplifiedAPIRequest.

Apply this diff to add type validation:

             # Map expected form fields to the SimplifiedAPIRequest schema
             if "input_value" in form:
-                data["input_value"] = form.get("input_value")
+                val = form.get("input_value")
+                if isinstance(val, str):
+                    data["input_value"] = val
             if "input_type" in form:
-                data["input_type"] = form.get("input_type")
+                val = form.get("input_type")
+                if isinstance(val, str):
+                    data["input_type"] = val
             if "output_type" in form:
-                data["output_type"] = form.get("output_type")
+                val = form.get("output_type")
+                if isinstance(val, str):
+                    data["output_type"] = val
             if "output_component" in form:
-                data["output_component"] = form.get("output_component")
+                val = form.get("output_component")
+                if isinstance(val, str):
+                    data["output_component"] = val
             if "session_id" in form:
-                data["session_id"] = form.get("session_id")
+                val = form.get("session_id")
+                if isinstance(val, str):
+                    data["session_id"] = val
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7460ee9 and 93766ba.

📒 Files selected for processing (1)
  • src/backend/base/langflow/api/v1/endpoints.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/backend/base/langflow/api/v1/endpoints.py (1)
src/backend/base/langflow/api/v1/schemas.py (1)
  • SimplifiedAPIRequest (338-347)
🪛 GitHub Actions: Ruff Style Check
src/backend/base/langflow/api/v1/endpoints.py

[error] 100-100: ruff check failed: E501 Line too long (121 > 120) in src/backend/base/langflow/api/v1/endpoints.py. Command: uv run --only-dev ruff check --output-format=github .

🪛 GitHub Check: Ruff Style Check (3.13)
src/backend/base/langflow/api/v1/endpoints.py

[failure] 101-101: Ruff (BLE001)
src/backend/base/langflow/api/v1/endpoints.py:101:28: BLE001 Do not catch blind exception: Exception


[failure] 100-100: Ruff (E501)
src/backend/base/langflow/api/v1/endpoints.py:100:121: E501 Line too long (121 > 120)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (18)
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 8/9
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 4/9
  • GitHub Check: Lint Backend / Run Mypy (3.10)
  • GitHub Check: Lint Backend / Run Mypy (3.12)
  • GitHub Check: Lint Backend / Run Mypy (3.11)
  • GitHub Check: Test Docker Images / Test docker images
  • GitHub Check: Lint Backend / Run Mypy (3.13)
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 1
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 2
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 4
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 5
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 3
  • GitHub Check: Run Backend Tests / LFX Tests - Python 3.10
  • GitHub Check: Run Backend Tests / Integration Tests - Python 3.10
  • GitHub Check: Test Starter Templates
  • GitHub Check: Optimize new Python code in this PR
  • GitHub Check: Update Component Index
  • GitHub Check: Update Starter Projects
🔇 Additional comments (1)
src/backend/base/langflow/api/v1/endpoints.py (1)

76-77: LGTM! Clean content-type detection.

The header extraction safely handles missing content-type headers and normalizes to lowercase for reliable matching.

Comment on lines 96 to 103
if "tweaks" in form:
raw_tweaks = form.get("tweaks")
if raw_tweaks:
try:
data["tweaks"] = orjson.loads(raw_tweaks) if isinstance(raw_tweaks, (str, bytes)) else raw_tweaks
except Exception:
# Leave as raw value if parsing fails
data["tweaks"] = raw_tweaks
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Improve exception handling and add type validation.

Two issues:

  1. The blind Exception catch on line 101 is too broad.
  2. Form fields might be UploadFile objects rather than strings if a client uploads a file under a field name like tweaks. This could cause downstream validation errors.

Apply this diff:

             # Tweaks may be JSON encoded in a form field
             if "tweaks" in form:
                 raw_tweaks = form.get("tweaks")
-                if raw_tweaks:
+                if raw_tweaks and isinstance(raw_tweaks, (str, bytes)):
                     try:
-                        data["tweaks"] = (
-                            orjson.loads(raw_tweaks) if isinstance(raw_tweaks, (str, bytes)) else raw_tweaks
-                        )
-                    except Exception:
+                        data["tweaks"] = orjson.loads(raw_tweaks)
+                    except (ValueError, orjson.JSONDecodeError):
                         # Leave as raw value if parsing fails
                         data["tweaks"] = raw_tweaks
🧰 Tools
🪛 GitHub Actions: Ruff Style Check

[error] 100-100: ruff check failed: E501 Line too long (121 > 120) in src/backend/base/langflow/api/v1/endpoints.py. Command: uv run --only-dev ruff check --output-format=github .

🪛 GitHub Check: Ruff Style Check (3.13)

[failure] 101-101: Ruff (BLE001)
src/backend/base/langflow/api/v1/endpoints.py:101:28: BLE001 Do not catch blind exception: Exception


[failure] 100-100: Ruff (E501)
src/backend/base/langflow/api/v1/endpoints.py:100:121: E501 Line too long (121 > 120)

raw_tweaks = form.get("tweaks")
if raw_tweaks:
try:
data["tweaks"] = orjson.loads(raw_tweaks) if isinstance(raw_tweaks, (str, bytes)) else raw_tweaks
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix line length to pass pipeline check.

Line 100 exceeds the 120-character limit, causing the Ruff style check to fail.

Apply this diff to split the line:

-                        data["tweaks"] = orjson.loads(raw_tweaks) if isinstance(raw_tweaks, (str, bytes)) else raw_tweaks
+                        data["tweaks"] = (
+                            orjson.loads(raw_tweaks) if isinstance(raw_tweaks, (str, bytes)) else raw_tweaks
+                        )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
data["tweaks"] = orjson.loads(raw_tweaks) if isinstance(raw_tweaks, (str, bytes)) else raw_tweaks
data["tweaks"] = (
orjson.loads(raw_tweaks) if isinstance(raw_tweaks, (str, bytes)) else raw_tweaks
)
🧰 Tools
🪛 GitHub Actions: Ruff Style Check

[error] 100-100: ruff check failed: E501 Line too long (121 > 120) in src/backend/base/langflow/api/v1/endpoints.py. Command: uv run --only-dev ruff check --output-format=github .

🪛 GitHub Check: Ruff Style Check (3.13)

[failure] 100-100: Ruff (E501)
src/backend/base/langflow/api/v1/endpoints.py:100:121: E501 Line too long (121 > 120)

🤖 Prompt for AI Agents
In src/backend/base/langflow/api/v1/endpoints.py around line 100, the single
line assigning data["tweaks"] exceeds the 120-character limit; break it into
multiple shorter lines so it fits the style guide. Specifically, compute
orjson.loads(raw_tweaks) only when raw_tweaks is a str or bytes and assign to
data["tweaks"] using a conditional expression split across lines (or use an
intermediate variable) so no line is longer than 120 characters and behavior
remains identical.

@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Nov 21, 2025
@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Nov 21, 2025
…to support session_id (fix langflow-ai#9859) changes made as per coderabbitai
@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Nov 21, 2025
@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Nov 21, 2025
@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Nov 21, 2025
@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Nov 21, 2025
@PrathameshJoshi123
Copy link
Author

Hello! I noticed the autofix.ci check is failing and I'm not sure if it requires action from me or if it's an automated issue. Could someone advise on how to proceed? Appreciate your help!

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

Labels

bug Something isn't working community Pull Request from an external contributor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

When sending text + image with the API and specifying a session_id, an error occurs.

1 participant