Skip to content

Skill stub docs (SKILL.md) have 3 accuracy bugs: missing await, wrong InertiaResponse import, missing Depends() binding #182

Description

@tmgbedu

Summary

The shipped SKILL.md stub docs under fastapi_startkit/skills/stubs/.ai/fastapi-startkit/ (and the copy under example/agents/.ai/fastapi-startkit/fastapi/SKILL.md) contain three accuracy bugs. These stubs are copied verbatim into consuming projects (e.g. via AISkillProvider / the skills scaffolding), so the bugs propagate downstream and lead agents/developers to write code that fails at runtime. Found and fixed locally while reviewing a fresh copy of these docs; filing upstream so the source stubs get corrected too.

Repo/branch checked: main @ 6b2aba8.

Bug 1 — Missing await on async ORM calls

Files:

masoniteorm/models/model.py defines create, update, find, find_or_fail, all, get, first as async def. The doc's own "Resourceful controllers" section (line 67 of the stubs copy) correctly shows await User.create(...), but three later examples drop the await:

# line 105-108 ("## ORM" usage example)
async def store(request: UserStoreRequest):
    user = User.create(request.model_dump())   # BUG: missing await
    ...
# line 126-128 (JsonApiResource example)
async def store(request: UserStoreRequest):
    user = User.create(request.model_dump())   # BUG: missing await
    return JsonResource(user)
# line 146-148 / 106-108 in example/agents copy ("## Architecture" action pattern)
def handle(self) -> JsonResource[User]:          # BUG: should be `async def`
    user = User.create(self.request.model_dump())  # BUG: missing await
    return JsonResource(user)

Following any of these examples verbatim returns an un-awaited coroutine into JsonResource(...), which breaks at runtime.

Suggested fix: add await to all three User.create(...) calls, and make handle() async def in the action-pattern example.

Bug 2 — Wrong InertiaResponse import

File: fastapi_startkit/src/fastapi_startkit/skills/stubs/.ai/fastapi-startkit/inertia/SKILL.md — lines 31 and 59

Both occurrences show:

from fastapi_startkit.inertia import Inertia, InertiaResponse

fastapi_startkit/inertia/__init__.py only exports Inertia, InertiaMiddleware, InertiaProvider (__all__ = ["Inertia", "InertiaMiddleware", "InertiaProvider"]) — InertiaResponse is not re-exported, so this import raises ImportError. The real, working import (see the framework's own fastapi_startkit/fastapi/requests/model.py sibling code and any generated app's home_controller.py) is:

from fastapi_startkit.inertia import Inertia
from fastapi_startkit.inertia.inertia import InertiaResponse

Suggested fix: update both occurrences (lines 31 and 59) to import InertiaResponse from fastapi_startkit.inertia.inertia.

Bug 3 — RequestModel example missing Depends() binding

File: same inertia stub, "## Request validation (Pydantic)" section, lines 120–156

The prose claims: "Type-hint a RequestModel parameter on a write method and FastAPI validates the submitted form before your controller runs", followed by:

async def store(request: ProjectStoreRequest):
    await Project.create(request.model_dump())
    return RedirectResponse(url="/projects", status_code=303)

This is a bare parameter — no Depends(). Per fastapi_startkit/src/fastapi_startkit/fastapi/requests/model.py, RequestModel.__pydantic_init_subclass__ builds a custom cls.__signature__ with per-field Form(...) defaults — but that custom signature is only consulted by FastAPI's dependency-injection machinery, i.e. only when the model is bound via Depends(ProjectStoreRequest). A bare request: ProjectStoreRequest param is treated by FastAPI as a plain Pydantic JSON body model, not form-encoded.

Since Inertia's useForm().post(...) submits multipart/form-data, a controller written exactly as shown would fail to bind the submitted data.

Suggested fix:

from fastapi import Depends
from fastapi.responses import RedirectResponse

from app.models import Project
from app.http.requests.project_store_request import ProjectStoreRequest


async def store(request: ProjectStoreRequest = Depends(ProjectStoreRequest)):
    await Project.create(request.model_dump())
    return RedirectResponse(url="/projects", status_code=303)

Impact

These stubs are the canonical source copied into every generated project's .ai/ / .claude/skills/ directories via the skills scaffolding (AISkillProvider), so the bugs affect every project that adopts them, including any resync of previously-generated copies.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions