[Bug] Queued messages (delivery='queue', status='admitted') are never promoted after the active turn completes — session idles with a non-empty queue
Nobody has claimed this yet.
- Dominant language
- No language data
- Stars
- 22
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Description
Pre-submission checklist
- I searched existing Issues and Discussions; the closest reports are #379 (queued inputs discarded with
session_resumedon resume) and #345 (queue lost on model error), but neither covers queued inputs that are never promoted at all while the session is idle. - I read
CONTRIBUTING.md. - User message bodies, local username, workspace paths, session/trace IDs are omitted or sanitized.
Category
Agent chat / queue promotion (turn-completed → next queued input)
Agent framework
ZCode Agent (first-party)
Severity
Blocking. Queued follow-ups are shown as pending chips in the UI but are never sent. Without an external workaround the user's messages are silently stuck forever (or lost to #379's resume-discard).
Reproducibility
Always. Measured on 2026-09-08/09 across 4 different sessions and 8+ queued inputs; the oldest stuck row had been sitting for 3 days. Reproduces on every busy session whenever a follow-up is typed while a turn is running.
Description
With interaction behavior set to queue, typing a follow-up while a turn is running persists the input correctly:
session_input: kind=sendText, delivery=queue, status=admitted
The problem is the promotion step after the turn ends. When the active turn finishes, the host goes fully idle (host log shows sessionStatus: "idle", activeTurnId: null, last turn_usage row completed), but the next queued row is not promoted into a new turn. The rows remain status=admitted indefinitely, the UI keeps showing the queued chips above the composer, and every new message typed later just appends to the queue. Nothing is sent.
Observed on top of that (nondeterministic):
- occasionally exactly one queued row gets promoted after some later turn completion — but the rest of the FIFO stays stuck, so order and delivery are unreliable;
- when a session is resumed, all unpromoted rows flip to
status=discarded, status_reason=session_resumed— that is #379.
Net effect: a queued message is effectively never delivered — either it stays admitted forever while the session idles, or it is discarded on resume.
Evidence (local DB, sanitized)
-- rows stuck for hours/days while the session was idle:
SELECT id, kind, delivery, status, time_created
FROM session_input
WHERE delivery='queue' AND status='admitted'
ORDER BY time_created;
-- 8 rows across 4 sessions; oldest created 3 days earlier;
-- all sessions had last turn_usage.status='completed' (idle)
A /-command queued the same way also never promotes.
Expected behavior
When the active turn transitions to completed/idle and session_input contains admitted rows for that session, the host should promote the next row (FIFO by admitted_sequence) into a new turn, same as when the queue was submitted while idle. If a resume must discard rows instead (see #379), their payloads should be surfaced/restored, not silently dropped.
Workaround I built (happy to contribute)
An external guard script polls session_input, and for stuck admitted rows (age ≥ 5 min, session idle) does: backup row → mark cancelled → re-inject the text verbatim via zcode --resume <sid> --cwd <dir> --prompt "<text>", FIFO per session, with crash recovery and duplicate protection (atomic UPDATE ... WHERE status='admitted', orphan-turn inference via the part table). It has delivered 10+ queued messages reliably; the queue only moves when this script runs, which confirms promotion is the missing piece. I can clean it up and share it if useful.
Environment
- ZCode Desktop: 3.9.2 (runtime schema 0.16.5) — same environment as #397
- CLI: 0.16.5
- OS: macOS 26.x (Darwin 25.6.0), Apple Silicon
- Model: GLM-5.3-Flash via built-in Z.ai provider
- Interaction behavior: queue
Related
- #379 — same rows (
delivery=queue), discarded on resume instead of promoted - #345 — queue lost on model error (goal mode)
- #397 — no turn starts after compact (promotion/turn-start family)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by locating the host's turn-completion handling and the session_input queue-promotion path, focusing on admitted rows and admitted_sequence. Reproduce by queueing a follow-up during an active turn, then verify the session becomes idle without promotion. Done means the next admitted row starts a new turn in FIFO order, including queued /-commands, without remaining stuck or being silently discarded.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- sql
- Domain
- backend, cli, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100