Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/renderer/hooks/remote/useAppRemoteEventListeners.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1015,6 +1015,20 @@ export function useAppRemoteEventListeners(deps: UseAppRemoteEventListenersDeps)
isRemote: false,
});

// Persist the new agent to disk synchronously before responding. The
// renderer's debounced persistence path (useDebouncedPersistence) is
// driven by React render cycles and a 2s timer, so a CLI consumer that
// runs `create-agent` and then immediately `list agents` / `send` would
// otherwise hit the disk-backed CLI storage layer before the in-memory
// session has been flushed — surfacing as `AGENT_NOT_FOUND` (issue #1013).
// `setMany` is incremental and idempotent: the debounced flush that
// follows simply rewrites the same row.
try {
await window.maestro.sessions.setMany([newSession], []);
} catch (persistErr) {
logger.error('[Remote] Failed to persist new CLI-created session:', undefined, persistErr);
}
Comment on lines +1026 to +1030
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Persistence failure is treated as success (false-positive create result).

On Line 1026, a failed setMany is logged but the handler still returns success, so CLI callers can get create-agent success even when disk persistence failed. Please fail the response path (and capture to Sentry) when this write fails.

Proposed fix
 			try {
 				await window.maestro.sessions.setMany([newSession], []);
 			} catch (persistErr) {
+				captureException(persistErr, {
+					extra: {
+						event: 'maestro:remoteCreateSession',
+						sessionId: newId,
+						toolType,
+						cwd,
+						responseChannel,
+					},
+				});
 				logger.error('[Remote] Failed to persist new CLI-created session:', undefined, persistErr);
+				window.maestro.process.sendRemoteCreateSessionResponse(responseChannel, null);
+				return;
 			}

As per coding guidelines: "Do not silently swallow errors... For unexpected errors, re-throw them... Use Sentry utilities (captureException, captureMessage) for explicit error reporting with context."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/renderer/hooks/remote/useAppRemoteEventListeners.ts` around lines 1026 -
1030, The code currently logs setMany failures but still treats the create path
as successful; update the handler in useAppRemoteEventListeners.ts so that when
window.maestro.sessions.setMany([newSession], []) throws, you call
Sentry.captureException(persistErr, { extra: { newSession } }) (or
captureMessage with context) and then re-throw or return a failed response so
the CLI sees failure instead of a false-positive; replace the current
logger.error(...) only behavior around window.maestro.sessions.setMany with
explicit Sentry capture and propagate the error (throw persistErr) so callers of
the create-agent path receive the failure.

Comment on lines +1026 to +1030
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Error swallowing hides unexpected failures from Sentry

The codebase's error-handling guideline (CLAUDE.md §Error Handling & Sentry) says unexpected errors should bubble up rather than be silently logged, so Sentry can capture them. A setMany failure is not a recoverable no-op — it means the contract "create returned success → agent is on disk" is broken. Re-throwing lets the outer catch send a proper failure response and keeps Sentry in the loop.

Suggested change
try {
await window.maestro.sessions.setMany([newSession], []);
} catch (persistErr) {
logger.error('[Remote] Failed to persist new CLI-created session:', undefined, persistErr);
}
try {
await window.maestro.sessions.setMany([newSession], []);
} catch (persistErr) {
logger.error('[Remote] Failed to persist new CLI-created session:', undefined, persistErr);
throw persistErr;
}

Context Used: CLAUDE.md (source)


window.maestro.process.sendRemoteCreateSessionResponse(responseChannel, {
sessionId: newId,
});
Comment on lines +1026 to 1034
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Silent persistence failure still delivers a success response

When setMany throws, the error is caught and logged but execution falls through to sendRemoteCreateSessionResponse with the valid sessionId. The CLI receives a success signal, immediately queries disk, and hits AGENT_NOT_FOUND — the exact race this PR is trying to eliminate. Re-throwing (or calling sendRemoteCreateSessionResponse(responseChannel, null) in the catch) is needed so the outer catch block returns a failure response that the CLI can act on, rather than a success response backed by a write that never landed.

Context Used: CLAUDE.md (source)

Expand Down