{"record":{"id":"b38e4bc71e642961","repo":"huggingface/smolagents","slug":"json-is-invalid-you-probably-tried-to-provide-mul","errorCode":null,"errorMessage":"JSON is invalid: you probably tried to provide multiple tool calls in one action. PROVIDE ONLY ONE TOOL CALL.","messagePattern":"JSON is invalid: you probably tried to provide multiple tool calls in one action\\. PROVIDE ONLY ONE TOOL CALL\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/smolagents/utils.py","lineNumber":179,"sourceCode":"    else:\n        # For any other type, convert to string\n        return str(obj)\n\n\ndef parse_json_blob(json_blob: str) -> tuple[dict[str, str], str]:\n    \"Extracts the JSON blob from the input and returns the JSON data and the rest of the input.\"\n    try:\n        first_accolade_index = json_blob.find(\"{\")\n        last_accolade_index = [a.start() for a in list(re.finditer(\"}\", json_blob))][-1]\n        json_str = json_blob[first_accolade_index : last_accolade_index + 1]\n        json_data = json.loads(json_str, strict=False)\n        return json_data, json_blob[:first_accolade_index]\n    except IndexError:\n        raise ValueError(\"The model output does not contain any JSON blob.\")\n    except json.JSONDecodeError as e:\n        place = e.pos\n        if json_blob[place - 1 : place + 2] == \"},\\n\":\n            raise ValueError(\n                \"JSON is invalid: you probably tried to provide multiple tool calls in one action. PROVIDE ONLY ONE TOOL CALL.\"\n            )\n        raise ValueError(\n            f\"The JSON blob you used is invalid due to the following error: {e}.\\n\"\n            f\"JSON blob was: {json_blob}, decoding failed on that specific part of the blob:\\n\"\n            f\"'{json_blob[place - 4 : place + 5]}'.\"\n        )\n\n\ndef extract_code_from_text(text: str, code_block_tags: tuple[str, str]) -> str | None:\n    \"\"\"Extract code from the LLM's output.\"\"\"\n    pattern = rf\"{code_block_tags[0]}(.*?){code_block_tags[1]}\"\n    matches = re.findall(pattern, text, re.DOTALL)\n    if matches:\n        return \"\\n\\n\".join(match.strip() for match in matches)\n    return None\n\n","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/huggingface/smolagents/blob/30bb1161095dbae2271e6bc3cc4c219cc3897a57/src/smolagents/utils.py#L161-L197","documentation":"A special case of JSON parsing failure in parse_json_blob: json.loads failed at a position where the blob contains '},\\n', i.e., two adjacent JSON objects. smolagents allows only ONE tool call per action, so this pattern is detected and reported with a targeted message.","triggerScenarios":"Model output contains multiple JSON action objects separated by a comma and newline, e.g. '{\"action\": ...},\\n{\"action\": ...}'; typically with models eager to parallelize tool calls.","commonSituations":"Strong models trying to batch several tool calls per step; prompts encouraging 'do everything at once'; few-shot examples accidentally showing multiple calls per action.","solutions":["Adjust the prompt/system template to demand exactly one tool call per step (the error text is designed to be fed back to the model)","Retry the step — the agent loop resubmits with this error as feedback","Use a model/template pairing known to comply with smolagents' one-call-per-step protocol"],"exampleFix":"# before (model output)\n{\"name\": \"search\", \"arguments\": {...}},\n{\"name\": \"visit\", \"arguments\": {...}}\n\n# after (one call per step)\n{\"name\": \"search\", \"arguments\": {...}}","handlingStrategy":"retry","validationCode":"def single_action_only(text: str) -> bool:\n    import re\n    return not re.search(r'\\}\\s*,\\s*\\{', text)","typeGuard":"def is_single_json_object(text: str) -> bool:\n    import json, re\n    m = re.search(r'\\{.*\\}', text, re.DOTALL)\n    if not m:\n        return False\n    try:\n        obj = json.loads(m.group(0))\n        return isinstance(obj, dict)\n    except json.JSONDecodeError:\n        return False","tryCatchPattern":"try:\n    parse_json_blob(text)\nexcept ValueError as e:\n    if 'PROVIDE ONLY ONE TOOL CALL' in str(e):\n        # return error to agent so model retries with one call\n        raise","preventionTips":["Prompt: 'provide exactly one tool call per step'","Avoid few-shot examples showing multiple actions per turn","Prefer native function-calling models for multi-tool tasks"],"tags":["smolagents","llm-output-parsing","json","tool-calling"],"backgroundTag":"invalid-model-json-output","analyzedSha":"30bb1161095dbae2271e6bc3cc4c219cc3897a57","analyzedAt":"2026-08-28T18:52:54.169Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}