From 81edf81d13089b3514ea148ba8215fad13a63d80 Mon Sep 17 00:00:00 2001 From: Kyle Pope Date: Mon, 16 Feb 2026 01:39:41 +0800 Subject: [PATCH] Fix MissingGreenlet on subtask serialization Chain second-level selectinload(ProjectTask.subtasks) on task create, update, and list endpoints. Pydantic's recursive ProjectTaskResponse schema accesses .subtasks on each subtask, which triggers lazy loading without eager load. Co-Authored-By: Claude Opus 4.6 --- backend/app/routers/projects.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/app/routers/projects.py b/backend/app/routers/projects.py index 1cc4c53..cba5762 100644 --- a/backend/app/routers/projects.py +++ b/backend/app/routers/projects.py @@ -128,7 +128,7 @@ async def get_project_tasks( query = ( select(ProjectTask) - .options(selectinload(ProjectTask.subtasks)) + .options(selectinload(ProjectTask.subtasks).selectinload(ProjectTask.subtasks)) .where( ProjectTask.project_id == project_id, ProjectTask.parent_task_id.is_(None), @@ -180,7 +180,7 @@ async def create_project_task( # Re-fetch with subtasks loaded query = ( select(ProjectTask) - .options(selectinload(ProjectTask.subtasks)) + .options(selectinload(ProjectTask.subtasks).selectinload(ProjectTask.subtasks)) .where(ProjectTask.id == new_task.id) ) result = await db.execute(query) @@ -217,7 +217,7 @@ async def update_project_task( # Re-fetch with subtasks loaded query = ( select(ProjectTask) - .options(selectinload(ProjectTask.subtasks)) + .options(selectinload(ProjectTask.subtasks).selectinload(ProjectTask.subtasks)) .where(ProjectTask.id == task_id) ) result = await db.execute(query)