Skip to content

fix(agent-teams): keep in-flight turns from failing when the store closes during shutdown - #412

Open
Ivancheng7 wants to merge 1 commit into
xvirobotics:mainfrom
Ivancheng7:fix/agent-team-store-close-race
Open

Ivancheng7 wants to merge 1 commit into
xvirobotics:mainfrom
Ivancheng7:fix/agent-team-store-close-race

Conversation

@Ivancheng7

Copy link
Copy Markdown
Contributor

Problem

AgentTeamStore.close() closes the SQLite connection during shutdown, but a turn that was already running may still be finalizing its card. The final-card path calls enrichWithAgentTeams(), which reads findTeamForChat() and status(). Once the connection is closed those reads throw The database connection is not open, so the turn is reported as task_error — exactly the turns that were in flight when the process restarted, i.e. the ones a restart should let finish.

Seen on a systemd-managed deployment: a systemctl restart window is enough to fail whatever turn was running at that moment.

Fix

  • AgentTeamStore tracks a closed flag: listTeams() / getTeam() (and everything built on them) return "no data" after close instead of throwing; close() is idempotent; isClosed() is exposed for callers.
  • enrichWithAgentTeams() skips enrichment once the store is closed, and treats any remaining read failure as auxiliary — the card renders without the team block instead of failing the turn.

The narrow race between the isClosed() check and the read remains (close() can land in between), which is why the caller treats a read failure as non-fatal rather than relying on the flag alone.

Tests

tests/agent-team-store.test.ts adds: read accessors after close, idempotent close. The full local suite on this branch matches upstream/main — no new failures.

…ring shutdown

AgentTeamStore.close() closes the SQLite connection while a turn may still be
finalizing: the final card path calls enrichWithAgentTeams(), which reads
findTeamForChat()/status(). After close those reads throw
"The database connection is not open", so a turn that was already running
when the process shut down is reported as task_error — precisely the turns a
restart should let finish.

- Track a closed flag; read accessors (listTeams/getTeam, and everything
  built on them) return "no data" instead of throwing; close() is idempotent.
- enrichWithAgentTeams() skips enrichment once the store is closed and treats
  any remaining read failure as auxiliary, so the card still renders.
- Tests: read accessors after close, idempotent close.

This branch has not been deployed

No deployments
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.

1 participant