{"record":{"id":"eeee20f0a15d83a2","repo":"FoundationAgents/OpenManus","slug":"invalid-tool-choice-tool-choice","errorCode":null,"errorMessage":"Invalid tool_choice: {tool_choice}","messagePattern":"Invalid tool_choice: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"app/llm.py","lineNumber":678,"sourceCode":"            timeout: Request timeout in seconds\n            tools: List of tools to use\n            tool_choice: Tool choice strategy\n            temperature: Sampling temperature for the response\n            **kwargs: Additional completion arguments\n\n        Returns:\n            ChatCompletionMessage: The model's response\n\n        Raises:\n            TokenLimitExceeded: If token limits are exceeded\n            ValueError: If tools, tool_choice, or messages are invalid\n            OpenAIError: If API call fails after retries\n            Exception: For unexpected errors\n        \"\"\"\n        try:\n            # Validate tool_choice\n            if tool_choice not in TOOL_CHOICE_VALUES:\n                raise ValueError(f\"Invalid tool_choice: {tool_choice}\")\n\n            # Check if the model supports images\n            supports_images = self.model in MULTIMODAL_MODELS\n\n            # Format messages\n            if system_msgs:\n                system_msgs = self.format_messages(system_msgs, supports_images)\n                messages = system_msgs + self.format_messages(messages, supports_images)\n            else:\n                messages = self.format_messages(messages, supports_images)\n\n            # Calculate input token count\n            input_tokens = self.count_message_tokens(messages)\n\n            # If there are tools, calculate token count for tool descriptions\n            tools_tokens = 0\n            if tools:\n                for tool in tools:","sourceCodeStart":660,"sourceCodeEnd":696,"githubUrl":"https://github.com/FoundationAgents/OpenManus/blob/52a13f2a57d8c7f6737eefb02ccf569594d44273/app/llm.py#L660-L696","documentation":"Raised by LLM.ask_with_tools() when the tool_choice argument is not in the module-level TOOL_CHOICE_VALUES constant (typically {\"auto\", \"none\", \"required\"} or the ToolChoice enum values). The validation runs before any message formatting or API call, so it is purely a caller-argument contract check.","triggerScenarios":"Calling ask_with_tools(messages, tools, tool_choice=\"always\"), tool_choice=\"tool\" (OpenAI's named-tool form is not supported here), or passing a non-canonical casing like \"Auto\". Passing None also fails if None is not among TOOL_CHOICE_VALUES.","commonSituations":"Copying OpenAI API examples that use named tool choice {\"type\":\"function\",...}; assuming arbitrary strings pass through; casing/typo mistakes from config-driven tool_choice values.","solutions":["Use one of the supported values: tool_choice=\"auto\" | \"none\" | \"required\" (or the ToolChoice enum)","If you load tool_choice from config, validate it against TOOL_CHOICE_VALUES at startup","For named-tool forcing, select the tool yourself before the call — this wrapper does not support it"],"exampleFix":"# before\nawait llm.ask_with_tools(msgs, tools, tool_choice={\"type\": \"function\", \"function\": {\"name\": \"search\"}})  # ValueError\n\n# after\nawait llm.ask_with_tools(msgs, tools=[search_tool], tool_choice=\"required\")","handlingStrategy":"type-guard","validationCode":"from app.llm import TOOL_CHOICE_VALUES\n\ndef valid_tool_choice(tool_choice: str | None) -> bool:\n    return tool_choice in TOOL_CHOICE_VALUES","typeGuard":"from typing import TypeGuard\nfrom app.llm import TOOL_CHOICE_VALUES\n\ndef is_tool_choice(value: object) -> TypeGuard[str]:\n    return isinstance(value, str) and value in TOOL_CHOICE_VALUES","tryCatchPattern":null,"preventionTips":["Whitelist config-driven tool_choice values against TOOL_CHOICE_VALUES at startup","Remember this wrapper accepts only auto/none/required — not OpenAI named-tool objects","Centralize tool_choice selection in one helper so validation lives in a single place"],"tags":["llm","tool-calling","validation","enum"],"backgroundTag":null,"analyzedSha":"52a13f2a57d8c7f6737eefb02ccf569594d44273","analyzedAt":"2026-08-15T02:33:49.993Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}