google-gemini/gemini-cli · warning · FatalCancellationError
Operation cancelled.
Error message
Operation cancelled.
What it means
Thrown immediately after wiring Ctrl+C to session.abort() when abortController.signal.aborted is already true at that point. It is a FatalCancellationError (exit code 130, the SIGINT convention). The operation was cancelled before the agentic loop's send() began.
Source
Thrown at packages/cli/src/nonInteractiveCliAgentSession.ts:318
content: input,
});
}
// Create LegacyAgentSession — owns the agentic loop
const session = new LegacyAgentSession({
client: geminiClient,
scheduler,
config,
promptId: prompt_id,
});
// Wire Ctrl+C to session abort
abortSession = () => {
void session.abort();
};
abortController.signal.addEventListener('abort', abortSession);
if (abortController.signal.aborted) {
throw new FatalCancellationError('Operation cancelled.');
}
// Start the agentic loop (runs in background)
const { streamId } = await session.send({
message: {
content: geminiPartsToContentParts(query),
displayContent: input,
},
});
if (streamId === null) {
throw new Error(
'LegacyAgentSession.send() unexpectedly returned no stream for a message send.',
);
}
const getTextContent = (parts?: ContentPart[]): string | undefined => {
const text = parts
?.map((part) => (part.type === 'text' ? part.text : ''))View on GitHub (pinned to 5024443c72)
Solutions
- This is expected cancellation behavior — no fix needed unless it fires without user intent.
- If spurious, ensure no external code is calling abortController.abort() during session bootstrap.
- Treat exit code 130 as a clean cancel rather than a crash in wrappers/CI.
Defensive patterns
Strategy: try-catch
Type guard
function isAbortSignal(v: unknown): v is AbortSignal {
return v instanceof AbortSignal;
} Try / catch
try {
await runAgentSession(input);
} catch (e) {
if (e instanceof FatalCancellationError) {
// exit code 130: clean cancel, do not treat as a failure in CI
process.exit(130);
}
throw e;
} Prevention
- Treat exit code 130 as a normal cancellation, not a crash, in wrappers/CI.
- Avoid calling abortController.abort() during session bootstrap unless intentional.
- Forward SIGINT cleanly to the CLI rather than killing the process abruptly.
When it happens
Trigger: An abort was requested (Ctrl+C or programmatic abortController.abort()) in the window between addEventListener('abort') and the session.send() call, so the signal is already aborted when the guard runs.
Common situations: User pressed Ctrl+C very early in a non-interactive run; a parent process/signaller fired abort during startup; double Ctrl+C where the first abort landed before the guard check.
Related errors
- Execution aborted
- Exiting due to an error processing the @ command.
- Reached max session turns for this session. Increase the num
- Operation aborted
- Exiting due to an error processing the @ command.
AI-assisted analysis of google-gemini/gemini-cli@5024443c72 (2026-08-12).
Data as JSON: /api/errors/d8816bf2ad0a9ba7.
Report an issue: GitHub.