{"record":{"id":"b181f788ad11a5ef","repo":"huggingface/smolagents","slug":"tool-call-needs-to-have-a-key-tool-name-key-g","errorCode":null,"errorMessage":"Tool call needs to have a key '{tool_name_key}'. Got keys: {list(tool_call_dictionary.keys())} instead","messagePattern":"Tool call needs to have a key '(.+?)'\\. Got keys: (.+?) instead","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/smolagents/models.py","lineNumber":405,"sourceCode":"            if flatten_messages_as_text:\n                content = message.content[0][\"text\"]\n            else:\n                content = message.content\n            output_message_list.append(\n                {\n                    \"role\": message.role,\n                    \"content\": content,\n                }\n            )\n    return output_message_list\n\n\ndef get_tool_call_from_text(text: str, tool_name_key: str, tool_arguments_key: str) -> ChatMessageToolCall:\n    tool_call_dictionary, _ = parse_json_blob(text)\n    try:\n        tool_name = tool_call_dictionary[tool_name_key]\n    except Exception as e:\n        raise ValueError(\n            f\"Tool call needs to have a key '{tool_name_key}'. Got keys: {list(tool_call_dictionary.keys())} instead\"\n        ) from e\n    tool_arguments = tool_call_dictionary.get(tool_arguments_key, None)\n    if isinstance(tool_arguments, str):\n        tool_arguments = parse_json_if_needed(tool_arguments)\n    return ChatMessageToolCall(\n        id=str(uuid.uuid4()),\n        type=\"function\",\n        function=ChatMessageToolCallFunction(name=tool_name, arguments=tool_arguments),\n    )\n\n\ndef supports_stop_parameter(model_id: str) -> bool:\n    \"\"\"\n    Check if the model supports the `stop` parameter.\n\n    Not supported with reasoning models openai/o3, openai/o4-mini, and the openai/gpt-5 series (and their versioned variants).\n","sourceCodeStart":387,"sourceCodeEnd":423,"githubUrl":"https://github.com/huggingface/smolagents/blob/30bb1161095dbae2271e6bc3cc4c219cc3897a57/src/smolagents/models.py#L387-L423","documentation":"For models that return tool calls as JSON text, smolagents parses the blob and requires it to contain the tool name under the configured tool_name_key (default 'name', set by tool_call_parser / model config). If the key is absent (or the blob isn't a dict mapping with that key), the KeyError is converted to ValueError listing the keys actually found. The tool_arguments_key (default 'arguments') is optional and defaults to None.","triggerScenarios":"A model emitting JSON like {\"action\": \"final_answer\", \"action_input\": ...} while the parser expects {'name': ..., 'arguments': ...}, or any tool-call JSON missing the configured name key; triggered via parse_tool_calls during chat post-processing.","commonSituations":"Using a custom/HF Inference model whose prompt format differs from the parser's expected key names; switching models without updating the tool call template; LLM emitting malformed or differently-keyed JSON.","solutions":["Align the model's tool-call JSON format with the parser: include the expected name key (e.g. {'name': ..., 'arguments': ...})","Adjust the system prompt/tool-call template so the model outputs the required keys","If the model uses different keys consistently, configure the parser's tool_name_key accordingly or wrap the model to remap keys","Retry/regenerate: LLMs occasionally omit keys; feeding the error back often fixes it"],"exampleFix":"# before (model output)\n{\"action\": \"get_weather\", \"action_input\": {\"city\": \"Paris\"}}\n\n# after (model output)\n{\"name\": \"get_weather\", \"arguments\": {\"city\": \"Paris\"}}","handlingStrategy":"fallback","validationCode":"from smolagents.utils import parse_json_blob\nparsed, _ = parse_json_blob(text)\nif 'name' not in parsed:\n    text = f\"{{\\\"name\\\": {parsed.get('action')}, \\\"arguments\\\": {parsed.get('action_input')}}}\"","typeGuard":"def has_tool_name_key(text: str, key: str = 'name') -> bool:\n    try:\n        blob, _ = parse_json_blob(text)\n        return isinstance(blob, dict) and key in blob\n    except Exception:\n        return False","tryCatchPattern":"try:\n    tool_call = get_tool_call_from_text(text, 'name', 'arguments')\nexcept ValueError as e:\n    if 'Tool call needs to have a key' in str(e):\n        text = regenerate_with_feedback(text, str(e))  # ask LLM to fix JSON","preventionTips":["Align the system prompt's tool-call JSON template with the parser keys","When swapping models, verify their JSON output keys match 'name'/'arguments'","Add a retry-with-error-feedback loop for malformed tool-call JSON"],"tags":["smolagents","tool-calls","json-parsing","llm-output"],"backgroundTag":"tool-call-schema-mismatch","analyzedSha":"30bb1161095dbae2271e6bc3cc4c219cc3897a57","analyzedAt":"2026-08-28T18:52:54.169Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}