You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
CRITICAL: work-item REST responses 500 with MissingGreenlet — _relations_to_list lazy-loads relations in async context #11684
POST /api/llc/work-items returns HTTP 500 even though the row IS created (verified: MVT-1..4 persisted). The failure is in response serialization, not creation. Any _item_to_dict caller whose item wasn't eager-loaded with relations is affected — create_work_item, and get_work_item/update/transition (they use _service().get(), which does a bare select(LLCWorkItem) with no relation eager-load).
Root cause
_relations_to_list (llc/api/work_items.py:312) does getattr(item, "outgoing_relations", []) — a lazy relationship load. Under an AsyncSession, a sync lazy-load raises:
sqlalchemy.exc.MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here.
list_work_items works only because list_by_project eager-loads relations; create/get/update/transition don't, so they 500. Live traceback: create_work_item (line 407) → _item_to_dict (368) → _relations_to_list (312) → MissingGreenlet.
Impact
The frontend work-item board's create/detail/update calls 500 despite the row being created — confusing UX (item appears only after refresh), and matches the earlier "Unable to create work items" report. (The CEO-chat create_task path is unaffected — it returns a minimal dict and never touches relations; verified: MVT-5 created cleanly.)
Fix
Make relation access async-safe at the single serialization seam: await item.awaitable_attrs.outgoing_relations (and await rel.awaitable_attrs.target) in an async _relations_to_list, called via await from _item_to_dict. awaitable_attrs returns cached values when already eager-loaded (GET/list path) and awaits a load otherwise — fixing all paths uniformly with no query duplication.
Acceptance
POST /api/llc/work-items {type:task} returns 201 with the item body.
Fixed by #11685 (merged, deployed). _relations_to_list now uses awaitable_attrs (+ AsyncAttrs on Base) so relation serialization is async-safe on create/get/update/transition. Verified live:POST /api/llc/work-items → 201 with relations: [] (was 500 MissingGreenlet). N+1 on target split out as #11686. Closing.
Activity
fix(llc): await _item_to_dict in coworker endpoint + null-target test…
fix(llc): enable awaitable_attrs via AsyncAttrs on Base; fix llc-e2e …
fix(llc): async-safe work-item relation serialization — fixes Missing…
github-actions commentedon Jul 11, 2026
PR #11685 (merged to
Dev_new_gui) references this issue with a close keyword.If this issue is fully resolved, close it manually. If work remains, no action is needed.
mrveiss commentedon Jul 11, 2026
Fixed by #11685 (merged, deployed).
_relations_to_listnow usesawaitable_attrs(+AsyncAttrson Base) so relation serialization is async-safe on create/get/update/transition. Verified live:POST /api/llc/work-items→ 201 withrelations: [](was 500 MissingGreenlet). N+1 ontargetsplit out as #11686. Closing.refactor(user-management): design new canonical declarative base (#12647