Skip to content

CRITICAL: work-item REST responses 500 with MissingGreenlet — _relations_to_list lazy-loads relations in async context #11684

Closed

Description

@mrveiss

Summary

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.
  • GET /api/llc/work-items/{id} returns 200.
  • list path still 200.

Activity

  1. github-actions commented on Jul 11, 2026

    @github-actions
    Contributor

    PR #11685 (merged to Dev_new_gui) references this issue with a close keyword.

    fix(llc): async-safe work-item relation serialization — fixes MissingGreenlet 500 (#11684)

    If this issue is fully resolved, close it manually. If work remains, no action is needed.

  2. mrveiss commented on Jul 11, 2026

    @mrveiss
    OwnerAuthor

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions