Skip to content

Bug: CLI create-agent doesn't persist to disk → subsequent send/list agents fail with AGENT_NOT_FOUND #1013

@Gl8be

Description

@Gl8be

Summary

When creating an agent via maestro-cli create-agent <name>, the agent is added to the running app's in-memory state (visible via status and in the UI) but never flushed to disk (maestro-sessions.json stays empty). All subsequent CLI commands that read from disk (list agents, send, show agent) fail with AGENT_NOT_FOUND, even though the agent is visible in the desktop app.

This breaks the entire "scriptable CLI agent creation → send prompt" workflow that create-agent was added to enable.

Environment

  • Maestro: v0.15.4-RC (portable build, auto-updated to installed via "Download and Install Update" on first launch)
  • OS: Windows 11 Pro (10.0.26200)
  • Node: bundled with Maestro
  • Installation path: C:\Users\GT\AppData\Local\Programs\Maestro\
  • Config path: %APPDATA%\Maestro\ (C:\Users\GT\AppData\Roaming\Maestro\)
  • Claude Code: C:\Users\GT\AppData\Roaming\npm\claude.cmd (npm install of @anthropic-ai/claude-code)

Reproduction

  1. Start Maestro desktop app

  2. Run:

    maestro-cli create-agent "Test Agent" \
      --cwd "C:\path\to\workspace" \
      --env "CLAUDE_CONFIG_DIR=C:\Users\<user>\.claude-other" \
      --json

    Output:

    {"success":true,"agentId":"80edc946-4034-4c98-a4d8-a9276b22584f","name":"Test Agent","type":"claude-code"}
  3. Verify agent appears in Maestro desktop UI (✅ visible in Left Bar)

  4. Verify in-memory state via maestro-cli status:

    Maestro is running on port 53054 with 1 agent
    
  5. Try to list agents via CLI:

    maestro-cli list agents --json

    Output: [] (empty)

  6. Try to send a message:

    maestro-cli send 80edc946-4034-4c98-a4d8-a9276b22584f "test"

    Output:

    {
      "success": false,
      "error": "Agent not found: 80edc946-4034-4c98-a4d8-a9276b22584f",
      "code": "AGENT_NOT_FOUND"
    }
  7. Inspect %APPDATA%\Maestro\maestro-sessions.json:

    {"sessions": []}

The agent is in app memory but not on disk.

Workaround attempts (none confirmed)

I tried two workarounds, both failed:

  1. Rename agent via UI (right-click → Rename → change a character → Save): useDebouncedPersistence did not flush. maestro-sessions.json remained {"sessions": []} even 10+ seconds after the rename was saved.
  2. Send a message manually from UI (paste prompt + Send): the message went through and produced output, but sessions.json still did not get the agent definition.

The persistence appears completely disconnected from in-memory state mutations for the duration of the running app. Possibly only graceful Quit triggers a flush (not tested yet — would lose in-flight session if so).

Hypothesis (root cause)

Reading the source:

  • src/cli/services/storage.ts: readSessions() reads maestro-sessions.json directly from disk (no IPC fallback).
  • src/cli/commands/send.ts: calls getSessionById()readSessions() → returns empty if file is empty.
  • src/renderer/hooks/utils/useDebouncedPersistence.ts: persists React session state to disk via window.maestro.sessions.setAll(...) — but only triggers when the React state changes (i.e., user UI action).

The create-agent IPC handler likely adds the agent to main process state and notifies the renderer, but the renderer's useDebouncedPersistence may not detect the change (or the debounce never fires because no follow-up React state mutation happens). Result: the agent lives only in main memory until a UI action triggers a flush.

Suggested fix

In the create-agent IPC handler (main process), after adding the agent to the in-memory session list, explicitly trigger a disk write — bypass the renderer-debounced path so CLI-driven mutations are immediately persistent. Two options:

  1. Main-side flush: call a persistSessionsNow() helper directly in the handler. Cleanest.
  2. CLI-side IPC fallback in storage.ts: when status reports the app is running on a known port, query agents via IPC instead of disk. Also handles the inverse case (UI changes not yet debounced).

Option 1 is narrower and matches the contract users would expect: "create-agent returned success → it's persisted, every other tool sees it".

The same bug likely affects any CLI command that mutates session state without going through the React layer (remove-agent, settings agent set if it touches sessions, etc.). A unified flush helper in the IPC handler would close the class of bugs.

Impact

Blocks the entire scripted/headless workflow that create-agent was added to enable: spin up agent → send first prompt → process result. This is exactly the use case for CI, cron jobs, batch processing — the marquee value of having a CLI in the first place.

Repro materials

Happy to provide:

  • Full maestro-debug-2026-05-18.log
  • Anonymized maestro-sessions.json snapshot pre/post workaround
  • Step-by-step screencast if useful

Filed during a Maestro evaluation spike — happy to test any patch on Windows 11.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions