[Bug] v3.4.2: Custom slash commands never appear — deferred-session hydration race leaves slashCommands permanently empty
Problem
After updating to v3.4.2 (Released Jul 22, 2026), custom slash commands defined in ~/.zcode/commands/ or <project>/.zcode/commands/ are no longer registered. The slash command picker shows "No slash commands have been broadcast for the current ZCode Agent session" even though:
- The command
.md file exists and parses correctly
- Plugin-shipped commands (code-review, commit, feature-dev) are also missing from the picker
- Skills and agents ARE discovered and shown correctly
This is a regression — the same command files worked in v3.3.6 and earlier. It affects every workspace, every session.
Root Cause
v3.4.2 introduced "non-project conversation mode" which creates sessions with persistence: "deferred" (draft sessions). The renderer populates the slash command list via a one-shot hydration effect that calls the agent backend to fetch configOptions + slashCommands for the newly-created session. But the deferred session is not yet persisted when the hydration query runs (~300ms later), so the agent throws "Session not found" and the .catch() handler silently leaves slashCommands: [] in the renderer store.
The hydration effect never retries. Sending messages, waiting, or restarting the agent process does not trigger re-hydration. The slash command list stays empty until the user manually clicks "Reload Session" in the workspace header.
Reproduction
- Install ZCode v3.4.2 on Windows 11.
- Create a custom command:
~/.zcode/commands/test-cmd.md with frontmatter:
---
description: A test command
---
Hello from test command
- Open any workspace in ZCode.
- Type
/ in the chat input.
Expected
The slash command picker shows /test-cmd (and plugin commands like /code-review, /commit).
Actual
The picker shows "No slash commands have been broadcast for the current ZCode Agent session." Only Skills and Agents sections are populated.
Evidence (agent logs)
From ~/.zcode/cli/log/zcode-2026-07-22.jsonl — two independent workspaces, same failure pattern:
Workspace 1: E:\ZCode\opencode-swarm
13:16:43.295 zcode_protocol.session_create.completed
sessionId: sess_3119333c-ed36-47d1-b310-14058caca6fa
persistence: "deferred"
workspacePath: "E:\ZCode\opencode-swarm"
13:16:43.683 zcode_protocol.v4.gateway_error (388ms later)
error: "Session not found: sess_3119333c-ed36-47d1-b310-14058caca6fa"
scope: "v4.hydrate"
Workspace 2: E:\ZCode
14:34:48.806 zcode_protocol.session_create.started
sessionId: sess_21fd9777-3c69-42b8-94a9-6da88fe9850a
persistence: "deferred"
workspacePath: "E:\ZCode"
14:34:49.081 zcode_protocol.session_create.completed (275ms)
14:34:49.356 zcode_protocol.v4.gateway_error (275ms after create)
error: "Session not found: sess_21fd9777-3c69-42b8-94a9-6da88fe9850a"
scope: "v4.hydrate"
Both sessions were created with persistence: "deferred". Both failed hydration with "Session not found" in scope: "v4.hydrate" within ~300-400ms of creation.
Plugin resolution confirms command roots exist but are never served to the renderer:
bootstrap.app.startup.plugins.completed:
commandRootCount: 3
diagnosticCount: 1
enabledPluginCount: 10
pluginStorageRoot: "C:\Users\Brett\.zcode\cli\plugins"
Workaround
Click the "Reload Session" button (circular arrow ⟳ icon in the workspace header). This triggers handleReloadSession, which restarts the workspace agent and re-runs TA() (session preparation). By the time the re-hydration query runs, the session has been promoted from deferred to immediate persistence, so the agent finds it and returns slash commands correctly.
Suggested Fix
The hydration effect should retry on "Session not found" with a short backoff, or the agent backend should await session persistence before responding to hydration queries for deferred sessions. Alternatively, slash commands could be populated from the session snapshot (which already includes slashCommands via Ak()) on every conversation frame update, rather than only during the one-shot hydration effect.
Relevant code locations (zcode.cjs, v3.4.2)
| Function |
Byte offset |
Role |
bSt.discoverCommands |
~11053114 |
Scans command roots, returns discovered commands |
fye (listZCodeCustomCommands) |
~11146334 |
Calls discoverCommands, catches errors → [] |
Ak (listProtocolSlashCommands) |
~11230737 |
Builds protocol slash command list, try/catch silently returns [] on failure |
In the renderer (index-GjXEi8_8.js):
XWe() hydration effect runs TA() → zcodeSessionService → on success calls setSlashCommands(). On failure (.catch()), sets config status to "error" but never retries.
lZe() reads slashCommands from the workspace store — returns [] because hydration failed.
GZe() renders emptyUnavailable text when slashCommands.length === 0.
Environment
- ZCode version: 3.4.2 (Desktop)
- OS: Windows 11 Pro (10.0.26200 x64)
- Plugin storage root:
C:\Users\Brett\.zcode\cli\plugins
- User config:
~/.zcode/cli/config.json
- Reproducibility: 100% — every workspace, every new session
[Bug] v3.4.2: Custom slash commands never appear — deferred-session hydration race leaves slashCommands permanently empty
Problem
After updating to v3.4.2 (Released Jul 22, 2026), custom slash commands defined in
~/.zcode/commands/or<project>/.zcode/commands/are no longer registered. The slash command picker shows "No slash commands have been broadcast for the current ZCode Agent session" even though:.mdfile exists and parses correctlyThis is a regression — the same command files worked in v3.3.6 and earlier. It affects every workspace, every session.
Root Cause
v3.4.2 introduced "non-project conversation mode" which creates sessions with
persistence: "deferred"(draft sessions). The renderer populates the slash command list via a one-shot hydration effect that calls the agent backend to fetchconfigOptions+slashCommandsfor the newly-created session. But the deferred session is not yet persisted when the hydration query runs (~300ms later), so the agent throws"Session not found"and the.catch()handler silently leavesslashCommands: []in the renderer store.The hydration effect never retries. Sending messages, waiting, or restarting the agent process does not trigger re-hydration. The slash command list stays empty until the user manually clicks "Reload Session" in the workspace header.
Reproduction
~/.zcode/commands/test-cmd.mdwith frontmatter:/in the chat input.Expected
The slash command picker shows
/test-cmd(and plugin commands like/code-review,/commit).Actual
The picker shows "No slash commands have been broadcast for the current ZCode Agent session." Only Skills and Agents sections are populated.
Evidence (agent logs)
From
~/.zcode/cli/log/zcode-2026-07-22.jsonl— two independent workspaces, same failure pattern:Workspace 1:
E:\ZCode\opencode-swarmWorkspace 2:
E:\ZCodeBoth sessions were created with
persistence: "deferred". Both failed hydration with"Session not found"inscope: "v4.hydrate"within ~300-400ms of creation.Plugin resolution confirms command roots exist but are never served to the renderer:
Workaround
Click the "Reload Session" button (circular arrow ⟳ icon in the workspace header). This triggers
handleReloadSession, which restarts the workspace agent and re-runsTA()(session preparation). By the time the re-hydration query runs, the session has been promoted fromdeferredtoimmediatepersistence, so the agent finds it and returns slash commands correctly.Suggested Fix
The hydration effect should retry on "Session not found" with a short backoff, or the agent backend should await session persistence before responding to hydration queries for deferred sessions. Alternatively, slash commands could be populated from the session snapshot (which already includes
slashCommandsviaAk()) on every conversation frame update, rather than only during the one-shot hydration effect.Relevant code locations (zcode.cjs, v3.4.2)
bSt.discoverCommandsfye(listZCodeCustomCommands)[]Ak(listProtocolSlashCommands)try/catchsilently returns[]on failureIn the renderer (
index-GjXEi8_8.js):XWe()hydration effect runsTA()→zcodeSessionService→ on success callssetSlashCommands(). On failure (.catch()), sets config status to"error"but never retries.lZe()readsslashCommandsfrom the workspace store — returns[]because hydration failed.GZe()rendersemptyUnavailabletext whenslashCommands.length === 0.Environment
C:\Users\Brett\.zcode\cli\plugins~/.zcode/cli/config.json