microsoft/semantic-kernel · info · OperationCancelledException
User stopped the operation
Error message
User stopped the operation
What it means
OperationCancelledException raised by the function-invocation filter sample when input() is interrupted: KeyboardInterrupt (Ctrl-C) or EOFError (Ctrl-D / closed stdin) is caught and re-raised as a Semantic Kernel OperationCancelledException, signalling the user is ending the interactive chat. It surfaces a deliberate, benign cancellation, not a fault.
Source
Thrown at python/samples/concepts/filtering/function_invocation_filters.py:36
# A filter is a piece of custom code that runs at certain points in the process
# this sample has a filter that is called during Function Invocation for non-streaming function.
# You can name the function itself with arbitrary names, but the signature needs to be:
# `context, next`
# You are then free to run code before the call to the next filter or the function itself.
# and code afterwards.
async def input_output_filter(
context: FunctionInvocationContext,
next: Callable[[FunctionInvocationContext], Coroutine[Any, Any, None]],
) -> None:
if context.function.plugin_name != "chat":
await next(context)
return
try:
user_input = input("User:> ")
except (KeyboardInterrupt, EOFError) as exc:
raise OperationCancelledException("User stopped the operation") from exc
if user_input == "exit":
raise OperationCancelledException("User stopped the operation")
context.arguments["chat_history"].add_user_message(user_input)
await next(context)
if context.result:
logger.info(f"Usage: {context.result.metadata.get('usage')}")
context.arguments["chat_history"].add_message(context.result.value[0])
print(f"Mosscap:> {context.result!s}")
async def main() -> None:
kernel = Kernel()
kernel.add_service(AzureChatCompletion(service_id="chat-gpt", credential=AzureCliCredential()))
kernel.add_plugin(
parent_directory=os.path.join(os.path.dirname(os.path.realpath(__file__)), "resources"), plugin_name="chat"
)View on GitHub (pinned to c028a0c7dc)
Solutions
- Treat this as a normal exit: catch OperationCancelledException at the top level and exit cleanly.
- If running non-interactively, replace input() with a different source (a queue, a file) or drive the chat without this filter.
- Press 'exit' (the string) to stop gracefully without relying on Ctrl-C/Ctrl-D.
Example fix
# before - cancellation propagates uncaught
try:
user_input = input("User:> ")
except (KeyboardInterrupt, EOFError) as exc:
raise OperationCancelledException("User stopped the operation") from exc
# after - handle at the call site
from semantic_kernel.exceptions import OperationCancelledException
try:
await kernel.invoke(chat_function)
except OperationCancelledException:
print("\nGoodbye!")
return Defensive patterns
Strategy: try-catch
Type guard
def is_cancellation(exc: BaseException) -> bool:
from semantic_kernel.exceptions import OperationCancelledException
return isinstance(exc, OperationCancelledException) Try / catch
from semantic_kernel.exceptions import OperationCancelledException
try:
await kernel.invoke(chat_function)
except OperationCancelledException:
print("\nChat cancelled by user.")
return Prevention
- Always catch OperationCancelledException at the top level of an interactive sample.
- Provide a non-exception exit (e.g. typing 'exit') to avoid relying on signals.
- Run interactive samples in a real TTY so EOF behaves predictably.
When it happens
Trigger: During the chat loop, the filter calls input('User:> '). The user presses Ctrl-C (KeyboardInterrupt) or Ctrl-D (EOFError, end of stdin). The except catches both and raises OperationCancelledException('User stopped the operation').
Common situations: Running the interactive sample in a terminal and pressing Ctrl-C/Ctrl-D to quit; running the sample under a non-interactive runner where stdin is closed; or piping input that ends.
Related errors
- Failed to get the weather
- Invalid operator
- No chart generated
- Invalid filename: would write outside the expected directory
- No chart generated
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/e67b963244413fcb.
Report an issue: GitHub.