Skip to content

Fix: team_task_list emits null for description/owner, hanging calling agents (#390)#391

Open
crystallyf1 wants to merge 2 commits into
iOfficeAI:mainfrom
crystallyf1:fix/team-task-list-null-fields
Open

Fix: team_task_list emits null for description/owner, hanging calling agents (#390)#391
crystallyf1 wants to merge 2 commits into
iOfficeAI:mainfrom
crystallyf1:fix/team-task-list-null-fields

Conversation

@crystallyf1
Copy link
Copy Markdown

Problem

team_task_list (exec_task_list in crates/aionui-team/src/mcp/server.rs) builds its per-task JSON result with json!({ ..., "description": t.description, "owner": t.owner, ... }). TeamTask::description and TeamTask::owner are Option<String>, so when a task has no description or owner the fields serialize to a bare JSON null.

Some MCP clients (Gemini / ACP) hang when a tool result contains null for these fields. In practice this freezes the calling agent and crashes spawned sub-agents the moment they call team_task_list on a board that has any task without a description/owner (which is the common case). Tracked in #390.

Fix

Map None to an empty string via .clone().unwrap_or_default(), so the fields are always emitted as strings ("") and clients never receive null. This mirrors the existing guard in exec_members, which already normalizes a missing agent status with unwrap_or(TeammateStatus::Idle) for the same reason.

"description": t.description.clone().unwrap_or_default(),
"owner": t.owner.clone().unwrap_or_default(),

Test

Adds a regression test exec_task_list_emits_empty_string_not_null_for_missing_fields in the existing mod tests. It replicates exec_task_list's per-task json! mapping against a TeamTask with description: None, owner: None and asserts the serialized JSON:

  • contains "description":"" and "owner":""
  • never contains "description":null or "owner":null

The test fails against the pre-fix mapping (serialized output was "description":null,...,"owner":null) and passes after the fix. Full cargo test -p aionui-team --lib is green (327 passed).

Closes #390

crystallyf1 and others added 2 commits June 3, 2026 15:47
…eAI#390)

`exec_task_list` built its per-task JSON with `json!({ ... "description": t.description, "owner": t.owner ... })`. When these optional fields were `None`, serde rendered them as a bare JSON `null`. Some MCP clients (Gemini/ACP) hang on `null` tool-result fields, which froze the calling agent and crashed spawned sub-agents (issue iOfficeAI#390).

Map `None` to an empty string via `.clone().unwrap_or_default()`, mirroring the existing `unwrap_or(Idle)` guard in `exec_members`. The output shape stays a string for those fields, so clients never receive `null`.

Add a regression test (`exec_task_list_emits_empty_string_not_null_for_missing_fields`) that replicates the per-task mapping against a `TeamTask` with `description: None, owner: None` and asserts the serialized JSON contains `"description":""`/`"owner":""` and never `"description":null`/`"owner":null`. The test fails against the pre-fix mapping and passes after the fix.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] team_task_list emits null fields (description/owner), hanging the calling agent — exec_members already guards against this

1 participant