# Langflow Input and Schema Validation Mechanisms: A Complete Technical Guide

> Explore Langflow's robust input and schema validation for API requests. Learn how FastAPI Pydantic and custom logic protect against attacks and ensure data integrity.

- Repository: [Langflow/langflow](https://github.com/langflow-ai/langflow)
- Tags: deep-dive
- Published: 2026-02-24

---

**Langflow employs a three-layered validation architecture combining FastAPI request parsing, Pydantic schema enforcement, and custom business-logic validators to secure API requests against malformed data, injection attacks, and SSRF vulnerabilities.**

The `langflow-ai/langflow` repository implements a defense-in-depth strategy for API request validation that spans from HTTP request parsing through to execution-time safety checks. This layered approach ensures that every flow execution request, code snippet, and external URL is sanitized before reaching the graph execution engine.

## FastAPI Request Parsing Layer

Every public endpoint in Langflow is mounted through FastAPI's `APIRouter`, which provides the first line of defense against malformed JSON payloads. The validation-specific routes are defined in **[`src/backend/base/langflow/api/v1/validate.py`](https://github.com/langflow-ai/langflow/blob/main/src/backend/base/langflow/api/v1/validate.py)**, where the router prefix isolates validation logic:

```python
router = APIRouter(prefix="/validate", tags=["Validate"])

```

When a client sends a request to endpoints like `/api/v1/flows/{flow_id}/run`, FastAPI automatically deserializes the JSON body into Pydantic models such as `SimplifiedAPIRequest`. If the incoming JSON cannot be parsed into the expected structure, FastAPI returns a **422 Unprocessable Entity** error before any application code executes, preventing invalid data from reaching business logic.

## Pydantic Schema Enforcement

Once parsing succeeds, Pydantic models enforce type constraints, field validations, and custom preprocessing through the `field_validator` decorator pattern.

### Core Request Models

The **`SimplifiedAPIRequest`** class in **[`src/backend/base/langflow/api/v1/schemas.py`](https://github.com/langflow-ai/langflow/blob/main/src/backend/base/langflow/api/v1/schemas.py)** serves as the primary schema for flow execution requests. It uses Pydantic V2 syntax to declare strict typing and default values:

```python
class SimplifiedAPIRequest(BaseModel):
    input_value: str | None = Field(default=None, description="The input value")
    input_type: InputType | None = Field(default="chat", description="The input type")
    output_type: OutputType | None = Field(default="chat", description="The output type")
    # Additional fields...

```

Similarly, the `FrontendNodeRequest` model in **[`src/backend/base/langflow/api/v1/base.py`](https://github.com/langflow-ai/langflow/blob/main/src/backend/base/langflow/api/v1/base.py)** handles component definitions, ensuring that optional fields like `imports` maintain a consistent error structure even when omitted.

### Field Validators

Pydantic validators run after type coercion but before the request reaches endpoint logic. For example, the `FrontendNodeRequest` model guarantees that import validation errors are always accessible:

```python
@field_validator("imports")
@classmethod
def validate_imports(cls, v):
    return v or {"errors": []}

```

These validators enforce constraints like non-empty strings, allowed enum values, and custom preprocessing such as URL trimming, ensuring downstream code receives predictable data structures.

## Custom Business-Logic Validation

After Pydantic validation completes, Langflow applies domain-specific validation rules through dedicated utility functions that protect against logical conflicts and security threats.

### Input and Tweaks Validation

The **`validate_input_and_tweaks`** function in **[`src/backend/base/langflow/api/v1/endpoints.py`](https://github.com/langflow-ai/langflow/blob/main/src/backend/base/langflow/api/v1/endpoints.py)** prevents ambiguous execution paths by detecting conflicts between top-level input values and component-specific tweaks:

```python
def validate_input_and_tweaks(input_request: SimplifiedAPIRequest) -> None:
    if not input_request.tweaks:
        return
    for key, value in input_request.tweaks.items():
        # Detects conflicts between input_value and tweak payloads

```

This routine raises `InvalidChatInputError` if a user attempts to send both a raw `input_value` and a tweak targeting the same component, ensuring deterministic flow execution.

### Code Validation

For custom component code, the **`validate_code`** function in **[`src/lfx/src/lfx/custom/validate.py`](https://github.com/langflow-ai/langflow/blob/main/src/lfx/src/lfx/custom/validate.py)** performs static analysis using Python's `ast` module:

1. Verifies syntax is well-formed
2. Extracts import statements
3. Locates a callable named `run` (or the first function) and verifies its signature

If validation fails, the function returns a structured dictionary with `imports` and `function` keys containing error details, which the API wraps in a `CodeValidationResponse`.

### Prompt Template Validation

Prompt validation occurs through **`process_prompt_template`** in **[`src/lfx/src/lfx/base/prompts/api_utils.py`](https://github.com/langflow-ai/langflow/blob/main/src/lfx/src/lfx/base/prompts/api_utils.py)**. This utility parses Mustache and Jinja2 syntax to extract variable requirements:

```python
input_variables = process_prompt_template(
    template=prompt_request.template,
    name=prompt_request.name,
    custom_fields=prompt_request.frontend_node.custom_fields,
    frontend_node_template=prompt_request.frontend_node.template,
    is_mustache=prompt_request.mustache,
)

```

The function returns a list of variable names that must be supplied by the frontend, preventing runtime template errors during flow execution.

### SSRF Protection

Components that perform external HTTP requests invoke **`validate_url_for_ssrf`** from **[`src/lfx/src/lfx/utils/ssrf_protection.py`](https://github.com/langflow-ai/langflow/blob/main/src/lfx/src/lfx/utils/ssrf_protection.py)** to block Server-Side Request Forgery attacks:

```python
validate_url_for_ssrf(url, warn_only=False)

```

This function validates hostnames against safety patterns and blocks internal network addresses (e.g., `127.0.0.1`, `169.254.169.254`). If an unsafe URL is detected, it raises `SSRFProtectionError`, which components catch and surface as API errors.

## Practical Implementation Examples

You can invoke Langflow's validation utilities directly in your own applications to ensure consistency with the platform's security model.

**Validate a user-supplied Python snippet:**

```python
from lfx.custom.validate import validate_code

code = """
import requests

def run(input):
    return {"output": input}
"""

result = validate_code(code)
print(result)  # {'imports': {'errors': []}, 'function': {'errors': []}}

```

**Extract variables from a Mustache template:**

```python
from lfx.base.prompts.api_utils import process_prompt_template

prompt = "Hello {{ name }}, today is {{ day }}."
variables = process_prompt_template(
    template=prompt,
    name="greeting",
    custom_fields=None,
    frontend_node_template=None,
    is_mustache=True,
)

print(variables)  # ['name', 'day']

```

**Guard against SSRF vulnerabilities:**

```python
from lfx.utils.ssrf_protection import validate_url_for_ssrf, SSRFProtectionError

url = "http://169.254.169.254/metadata"
try:
    validate_url_for_ssrf(url, warn_only=False)
except SSRFProtectionError as exc:
    print(f"Blocked URL: {exc}")

```

**Validate a flow execution payload:**

```python
from langflow.api.v1.schemas import SimplifiedAPIRequest
from langflow.api.v1.endpoints import validate_input_and_tweaks

payload = SimplifiedAPIRequest(
    input_value="Hello",
    input_type="chat",
    tweaks={"ChatInput": {"input_value": "Hello"}}
)

# Raises InvalidChatInputError due to conflicting input methods

validate_input_and_tweaks(payload)

```

## Summary

Langflow's input and schema validation mechanisms operate through three coordinated layers:

- **FastAPI parsing** handles JSON deserialization and returns 422 errors for malformed requests before application logic executes
- **Pydantic schemas** enforce type safety and field constraints through models like `SimplifiedAPIRequest` and custom `field_validator` decorators
- **Business-logic validators** provide domain-specific security checks including input/tweak conflict detection, Python code static analysis, template variable extraction, and SSRF URL filtering

This architecture ensures that malformed data, injection attempts, and unsafe external requests are intercepted before reaching the graph execution engine.

## Frequently Asked Questions

### How does Langflow prevent SSRF attacks in API components?

Langflow prevents SSRF attacks through the `validate_url_for_ssrf` function in [`src/lfx/src/lfx/utils/ssrf_protection.py`](https://github.com/langflow-ai/langflow/blob/main/src/lfx/src/lfx/utils/ssrf_protection.py). This utility checks URLs against a whitelist of safe patterns and blocks internal IP addresses including `127.0.0.1` and cloud metadata endpoints like `169.254.169.254`. When an unsafe URL is detected, the function raises `SSRFProtectionError`, which API components catch and convert into user-facing error responses.

### What happens if I send conflicting input values and tweaks to a flow endpoint?

If you send both a top-level `input_value` and a tweak targeting the same component (e.g., `ChatInput`), the `validate_input_and_tweaks` function in [`src/backend/base/langflow/api/v1/endpoints.py`](https://github.com/langflow-ai/langflow/blob/main/src/backend/base/langflow/api/v1/endpoints.py) raises `InvalidChatInputError`. This validation ensures deterministic execution by preventing ambiguous input paths where the system cannot determine which value should take precedence.

### Can I use Langflow's code validation outside the API context?

Yes, you can import `validate_code` from [`src/lfx/src/lfx/custom/validate.py`](https://github.com/langflow-ai/langflow/blob/main/src/lfx/src/lfx/custom/validate.py) to validate Python code snippets in any Python environment. The function uses the `ast` module to parse syntax, extract imports, and verify that a `run` function exists with the correct signature, returning a structured error report that matches the API's validation responses.

### Which Pydantic models handle the main flow execution requests?

The primary model for flow execution requests is `SimplifiedAPIRequest` defined in [`src/backend/base/langflow/api/v1/schemas.py`](https://github.com/langflow-ai/langflow/blob/main/src/backend/base/langflow/api/v1/schemas.py). This model validates fields including `input_value`, `input_type`, `output_type`, and `tweaks` using Pydantic V2's `field_validator` decorators. For component-specific requests, `FrontendNodeRequest` in [`src/backend/base/langflow/api/v1/base.py`](https://github.com/langflow-ai/langflow/blob/main/src/backend/base/langflow/api/v1/base.py) handles validation of node configurations and imports.