AnswerDotAI / AnswerDotAI/fasthtml

[BUG] Missing function type hints result in `None` for function inputs in FastHTML

Open
#625 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Jupyter Notebook
Stars
7k
Forks
319
Avg merge
28m
Merged PRs (30d)
3

Description

## Description

When using FastHTML, omitting type hints for function parameters causes input values to default to None, resulting in a TypeError. This behavior is inconsistent with the expected functionality where inputs should retain their values regardless of type hints.

## Issue

Below is a sample code (adapted from [FastHTML Tutorials](https://docs.fastht.ml/tutorials/by_example.html#htmx)):

```python
import fasthtml.components as fh_components
from fasthtml.core import FastHTML, serve

app = FastHTML()
route = app.route

@app.get("/")
def home():
return fh_components.Form(
fh_components.Input(type="text", id="input_1", name="input 1"),
fh_components.Input(type="text", id="input_2", name="input 2"),
fh_components.Button("Submit", id="submit", hx_post="/submit", hx_target="#response"),
), fh_components.Div(id="response")

@app.post("/submit")
def demo_fn(input_1: str, input_2: str):
response = inp_1 + " " + inp_2
return response

serve()
```
The above code works perfectly!

but if we change the demo_fn removing the type hints as:
```python
@app.post("/submit")
def demo_fn(input_1, input_2):
response = inp_1 + " " + inp_2
return response
```

This throws error:
```
File "/workspaces/demoapp/test.py", line 17, in demo_fn
response = inp_1 + " " + inp_2
~~~~~~^~~~~
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
```

on debugging, we found that missing types are making the values `None` for some weird reason.
This must be a bug in how fastHTL handles the data!

## Expected behavior

FastHTML should not convert the function inputs to `None` if the function input param type hints are missing.

## Found workaround/fix

A workaround was found, by tapping into the form request. but this should work without this hack/workaround.
here is the workaround:

```python
import fasthtml.components as fh_components
from fasthtml.core import FastHTML, serve, Request

app = FastHTML()
route = app.route

@app.get("/")
def home():
return fh_components.Form(
fh_components.Input(type="text", id="input_1", name="input 1"),
fh_components.Input(type="text", id="input_2", name="input 2"),
fh_components.Button("Submit", id="submit", hx_post="/submit", hx_target="#response"),
), fh_components.Div(id="response")

@app.post("/submit")
async def demo_fn(request: Request):
form_data = await request.form()
input_1 = form_data.get("input_1")
input_2 = form_data.get("input_2")
return input_1 + input_2

serve()
```

PS: discovered this bug & workaround while working on a project with @soumik12345

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the issue with the FastHTML route and demo_fn entry points shown in the report, comparing parameter binding with and without type annotations. Inspect how FastHTML handles the Request and route parameters, then verify that unannotated form inputs retain their submitted values without the workaround.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.