microsoft/semantic-kernel · warning · ValueError
Invalid operator
Error message
Invalid operator
What it means
A sample-only ValueError raised by the local calculator() inner function when the 'operator' argument is not one of '+', '-', '*', '/'. It is demonstration logic inside an autogen sample, not part of the Semantic Kernel library surface. It exists to show how a tool function reports an invalid argument back to the agent.
Source
Thrown at python/samples/concepts/agents/autogen_conversable_agent/autogen_conversable_agent_convo_with_tools.py:39
This sample follows the AutoGen flow outlined here:
https://microsoft.github.io/autogen/0.2/docs/tutorial/tool-use
"""
Operator = Literal["+", "-", "*", "/"]
async def main():
def calculator(a: int, b: int, operator: Annotated[Operator, "operator"]) -> int:
if operator == "+":
return a + b
if operator == "-":
return a - b
if operator == "*":
return a * b
if operator == "/":
return int(a / b)
raise ValueError("Invalid operator")
assistant = ConversableAgent(
name="Assistant",
system_message="You are a helpful AI assistant. "
"You can help with simple calculations. "
"Return 'TERMINATE' when the task is done.",
# Note: the model "gpt-4o" leads to a "division by zero" error that doesn't occur with "gpt-4o-mini"
# or even "gpt-4".
llm_config={
"config_list": [{"model": os.environ["OPENAI_CHAT_MODEL_ID"], "api_key": os.environ["OPENAI_API_KEY"]}]
},
)
# Create a thread for use with the agent.
thread: AutoGenConversableAgentThread = None
# Create a Semantic Kernel AutoGenConversableAgent based on the AutoGen ConversableAgent.
assistant_agent = AutoGenConversableAgent(conversable_agent=assistant)View on GitHub (pinned to c028a0c7dc)
Solutions
- Call calculator only with one of '+', '-', '*', '/'.
- If you need more operators (%, **, //), extend the if-chain before the raise.
- Normalize the operator before dispatch (e.g. map 'plus'->'+', '×'->'*').
- Make the Operator type a Literal/Enum so callers see allowed values up front.
Example fix
# before
async def main():
def calculator(a: int, b: int, operator: Annotated[Operator, "operator"]) -> int:
if operator == "+":
return a + b
# ...
raise ValueError("Invalid operator")
# after - typed operator + extra ops + normalization
from typing import Literal
Op = Literal["+", "-", "*", "/", "%"]
def calculator(a: int, b: int, operator: Op) -> int:
mapping = {"plus": "+", "minus": "-", "times": "*", "divide": "/"}
operator = mapping.get(operator, operator)
ops = {"+": lambda: a + b, "-": lambda: a - b,
"*": lambda: a * b, "/": lambda: int(a / b),
"%": lambda: a % b}
if operator not in ops:
raise ValueError(f"Invalid operator: {operator!r}")
return ops[operator]() Defensive patterns
Strategy: validation
Validate before calling
ALLOWED = {"+", "-", "*", "/"}
def safe_calc(a, b, operator):
operator = {"plus": "+", "minus": "-", "times": "*", "divide": "/"}.get(operator, operator)
if operator not in ALLOWED:
raise ValueError(f"Invalid operator: {operator!r}. Use one of {sorted(ALLOWED)}.")
return {"+": a + b, "-": a - b, "*": a * b, "/": int(a / b)}[operator] Type guard
from typing import Literal
Op = Literal["+", "-", "*", "/"]
def is_valid_operator(op: object) -> bool:
return op in ("+", "-", "*", "/") Try / catch
try:
result = calculator(a, b, op)
except ValueError as e:
# report back to the agent / caller with the allowed set
print(f"{e}. Supported operators: + - * /") Prevention
- Type the operator parameter as Literal['+','-','*','/'] so the model sees allowed values.
- Describe allowed operators in the function docstring/annotation so the LLM does not invent synonyms.
- Normalize synonyms before dispatch.
When it happens
Trigger: The LLM/agent or a direct caller invokes calculator(a, b, operator) with an operator value outside the four supported strings (e.g. '%', '^', 'plus', '', or a typo).
Common situations: The model passes a synonym ('plus'), a unicode operator, or an unsupported operator; or you reuse the sample's calculator verbatim and call it programmatically with a non-whitelisted value.
Related errors
- No chart generated
- No chart generated
- Radius and height must be non-negative.
- City '{city}' is not in the list of cities: {', '.join(citie
- Message role must be either Assistant or User.
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/38bec5726609f0bc.
Report an issue: GitHub.