google-gemini/gemini-cli · warning · Error

Operation aborted

Error message

Operation aborted

What it means

Thrown inside the streaming loop of RemoteAgentInvocation.execute() when _signal.aborted becomes true between chunks. This is the cooperative-cancellation path: an external AbortSignal (user cancel, parent abort, timeout) fired while consuming the remote agent's response stream.

Source

Thrown at packages/core/src/agents/remote-invocation.ts:188

      }

      const message = this.params.query;

      const stream = this.clientManager.sendMessageStream(
        this.definition.name,
        message,
        {
          contextId: this.contextId,
          taskId: this.taskId,
          signal: _signal,
        },
      );

      let finalResponse: SendMessageResult | undefined;

      for await (const chunk of stream) {
        if (_signal.aborted) {
          throw new Error('Operation aborted');
        }
        finalResponse = chunk;
        reassembler.update(chunk);

        if (updateOutput) {
          updateOutput({
            isSubagentProgress: true,
            agentName,
            state: SubagentState.RUNNING,
            recentActivity: reassembler.toActivityItems(),
            result: reassembler.toString(),
          });
        }

        const {
          contextId: newContextId,
          taskId: newTaskId,
          clearTaskId,

View on GitHub (pinned to 5024443c72)

Solutions

  1. Treat as expected cancellation — surface a 'cancelled by user' message rather than an error where appropriate.
  2. If unintended, investigate which AbortController is aborting the signal (timeout, parent shutdown).
  3. Ensure cleanup in the finally block persists session state (it does) so the conversation can resume.
  4. Raise the relevant timeout if the abort came from a too-short deadline.
Defensive patterns

Strategy: try-catch

Validate before calling

// Pass a signal with a generous deadline and avoid aborting mid-stream unless intended.
const ctrl = new AbortController();
const timer = setTimeout(() => ctrl.abort(), 5 * 60_000);
// ... pass ctrl.signal, clear timer when done.

Type guard

function isAbortError(e) {
  return e instanceof Error && (e.name === 'AbortError' || /Operation aborted/.test(e.message));
}

Try / catch

try {
  await invocation.execute({ abortSignal: signal });
} catch (e) {
  if (e instanceof Error && e.message === 'Operation aborted') {
    // user/parent cancellation — report cleanly, do not rethrow as a hard error
    return { cancelled: true };
  }
  throw e;
}

Prevention

When it happens

Trigger: for await (const chunk of stream) checks _signal.aborted each iteration; any abort (user pressed stop, the parent task was cancelled, a timeout aborted the signal) flips the flag and this throws on the next iteration.

Common situations: User cancels the running agent; a parent subagent is aborted; an AbortController timeout fires mid-stream; upstream scheduler cancels the task.

Related errors


AI-assisted analysis of google-gemini/gemini-cli@5024443c72 (2026-08-12). Data as JSON: /api/errors/8d5f7f6511dbbde1. Report an issue: GitHub.