{"record":{"id":"78a7b1f69372f609","repo":"langchain-ai/langchain","slug":"unknown-tool-type-res-type-r-available-tool","errorCode":null,"errorMessage":"Unknown tool type: {res['type']!r}. Available tools: {available}","messagePattern":"Unknown tool type: (.+?)\\. Available tools: (.+?)","errorType":"exception","errorClass":"OutputParserException","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/output_parsers/openai_tools.py","lineNumber":365,"sourceCode":"        pydantic_objects = []\n        for res in json_results:\n            if not isinstance(res[\"args\"], dict):\n                if partial:\n                    continue\n                msg = (\n                    f\"Tool arguments must be specified as a dict, received: \"\n                    f\"{res['args']}\"\n                )\n                raise ValueError(msg)\n\n            try:\n                tool = name_dict[res[\"type\"]]\n            except KeyError as e:\n                available = \", \".join(name_dict.keys()) or \"<no_tools>\"\n                msg = (\n                    f\"Unknown tool type: {res['type']!r}. Available tools: {available}\"\n                )\n                raise OutputParserException(msg) from e\n\n            try:\n                pydantic_objects.append(tool(**res[\"args\"]))\n            except (ValidationError, ValueError):\n                if partial:\n                    continue\n                has_max_tokens_stop_reason = any(\n                    generation.message.response_metadata.get(\"stop_reason\")\n                    == \"max_tokens\"\n                    for generation in result\n                    if isinstance(generation, ChatGeneration)\n                )\n                if has_max_tokens_stop_reason:\n                    logger.exception(_MAX_TOKENS_ERROR)\n                raise\n        if self.first_tool_only:\n            return pydantic_objects[0] if pydantic_objects else None\n        return pydantic_objects","sourceCodeStart":347,"sourceCodeEnd":383,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/output_parsers/openai_tools.py#L347-L383","documentation":"Raised by PydanticToolsParser.parse_result when the model calls a tool whose name (res['type']) is not in the parser's name_dict of provided Pydantic tool schemas. The message lists the requested name and all available tool names to make the mismatch obvious.","triggerScenarios":"Model hallucinates a tool name not in the provided schemas (e.g. 'search_web' when only 'web_search' exists); parser constructed with a tools list that is out of sync with what was bound to the model; typo between bind_tools names and PydanticToolsParser(tools=[...]).","commonSituations":"Renaming a tool in one place but not the other; models inventing plausible tool names; few-shot examples in prompts referencing tools that are not actually registered.","solutions":["Align the tools list passed to PydanticToolsParser with the tools bound to the model (same classes/names)","Make tool names unambiguous and consistent (check Pydantic model titles vs field names) to reduce hallucination","Catch OutputParserException, inspect the 'Available tools' list in the message, and retry with corrected registration"],"exampleFix":"# before\nllm = llm.bind_tools([WebSearch])\nparser = PydanticToolsParser(tools=[Search])  # name mismatch -> hallucinated lookups fail\n\n# after\nllm = llm.bind_tools([WebSearch])\nparser = PydanticToolsParser(tools=[WebSearch])","handlingStrategy":"try-catch","validationCode":"known = {t.__name__ for t in tools}\nunknown = [r[\"type\"] for r in json_results if r[\"type\"] not in known]\nif unknown:\n    ...  # log/re-prompt before parsing","typeGuard":null,"tryCatchPattern":"from langchain_core.exceptions import OutputParserException\ntry:\n    objs = parser.parse_result(result)\nexcept OutputParserException as e:\n    if \"Unknown tool type\" in str(e):\n        objs = parser.parse_result(result, partial=True) or []  # skip unknown, keep known","preventionTips":["Bind the exact same tool classes to the model and the parser","Keep tool names distinct and stable across refactors"],"tags":["tool-calling","pydantic","configuration","model-behavior"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}