Bug
When agents.list is configured in openclaw.json, ACP sessions spawned via sessions_spawn with runtime: "acp" are invisible to sessions_list and related tools.
Root Cause
loadCombinedSessionStoreForGateway() in src/gateway/session-utils.ts calls listConfiguredAgentIds() which, when agents.list is populated, only returns agent IDs from the config (e.g. main, leon). It never falls through to the disk scan path (listExistingAgentIdsFromDisk()).
ACP sessions are stored under dynamically-created agent dirs like agents/codex/sessions/ and agents/claude/sessions/. Since codex and claude aren't in agents.list, their session stores are never scanned.
Steps to Reproduce
- Have
agents.list configured with at least one agent (e.g. main)
- Enable ACP:
acp.enabled: true, backend: "acpx", allowedAgents: ["claude", "codex"]
- Spawn an ACP session:
sessions_spawn({ runtime: "acp", agentId: "codex", task: "...", mode: "run" })
- Session returns
status: "accepted" with a childSessionKey
sessions_list does not show the session
- The session IS present in
~/.openclaw/agents/codex/sessions/sessions.json with ACP metadata
Expected Behavior
ACP sessions should be visible in sessions_list regardless of whether their agent ID is in agents.list.
Suggested Fix
listConfiguredAgentIds() should merge the config list with the disk scan, so dynamically-created ACP agent directories are included:
function listConfiguredAgentIds(cfg: OpenClawConfig): string[] {
const ids = new Set<string>();
const defaultId = normalizeAgentId(resolveDefaultAgentId(cfg));
ids.add(defaultId);
// Always include configured agents
for (const entry of cfg.agents?.list ?? []) {
if (entry?.id) ids.add(normalizeAgentId(entry.id));
}
// Always include agents that exist on disk (covers ACP-created dirs)
for (const id of listExistingAgentIdsFromDisk()) {
ids.add(id);
}
const sorted = Array.from(ids).filter(Boolean);
sorted.sort((a, b) => a.localeCompare(b));
return sorted.includes(defaultId)
? [defaultId, ...sorted.filter((id) => id !== defaultId)]
: sorted;
}
Additional Issues Observed
- No
.jsonl transcript files are created for ACP sessions (the ACP code path in dispatch-acp.ts never writes to SessionManager)
- ACP sessions show
state: error with acpx exited with code 5 even when the agent successfully completed work (commits were made). This suppresses completion announcements.
Environment
- OpenClaw version: 2026.3.3
- acpx version: 0.1.15
- Config:
agents.list with main and leon; acp.allowedAgents: ["claude", "codex"]
Bug
When
agents.listis configured inopenclaw.json, ACP sessions spawned viasessions_spawnwithruntime: "acp"are invisible tosessions_listand related tools.Root Cause
loadCombinedSessionStoreForGateway()insrc/gateway/session-utils.tscallslistConfiguredAgentIds()which, whenagents.listis populated, only returns agent IDs from the config (e.g.main,leon). It never falls through to the disk scan path (listExistingAgentIdsFromDisk()).ACP sessions are stored under dynamically-created agent dirs like
agents/codex/sessions/andagents/claude/sessions/. Sincecodexandclaudearen't inagents.list, their session stores are never scanned.Steps to Reproduce
agents.listconfigured with at least one agent (e.g.main)acp.enabled: true, backend: "acpx", allowedAgents: ["claude", "codex"]sessions_spawn({ runtime: "acp", agentId: "codex", task: "...", mode: "run" })status: "accepted"with achildSessionKeysessions_listdoes not show the session~/.openclaw/agents/codex/sessions/sessions.jsonwith ACP metadataExpected Behavior
ACP sessions should be visible in
sessions_listregardless of whether their agent ID is inagents.list.Suggested Fix
listConfiguredAgentIds()should merge the config list with the disk scan, so dynamically-created ACP agent directories are included:Additional Issues Observed
.jsonltranscript files are created for ACP sessions (the ACP code path indispatch-acp.tsnever writes toSessionManager)state: errorwithacpx exited with code 5even when the agent successfully completed work (commits were made). This suppresses completion announcements.Environment
agents.listwithmainandleon;acp.allowedAgents: ["claude", "codex"]