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

  1. Call calculator only with one of '+', '-', '*', '/'.
  2. If you need more operators (%, **, //), extend the if-chain before the raise.
  3. Normalize the operator before dispatch (e.g. map 'plus'->'+', '×'->'*').
  4. 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

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


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/38bec5726609f0bc. Report an issue: GitHub.