datawhalechina/hello-agents · error · RuntimeError

JSON 校验失败且没有剩余调用次数:{error}

Error message

JSON 校验失败且没有剩余调用次数:{error}

What it means

A RuntimeError raised by run_structured when parsing the model response fails (ValueError from extract_json_object or JSONDecodeError, both ValueError subclasses) and the budget has no calls left for a repair attempt. It chains the original error (raise ... from error), so the message embeds the concrete parse failure that could not be repaired in time.

Source

Thrown at Co-creation-projects/Henry2513-MeetingActionAgent/main.ipynb:321

    "        self.used += 1\n",
    "        return agent.run(prompt)\n",
    "\n",
    "\n",
    "# 调用 Agent 并将响应解析为指定的数据模型。\n",
    "def run_structured(\n",
    "    agent,\n",
    "    prompt: str,\n",
    "    model_type: type[BaseModel],\n",
    "    budget: CallBudget,\n",
    ") -> BaseModel:\n",
    "    schema = json.dumps(model_type.model_json_schema(), ensure_ascii=False)\n",
    "    full_prompt = f\"{prompt}\\n\\n必须遵循以下 JSON Schema:\\n{schema}\"\n",
    "    raw_response = budget.run(agent, full_prompt)\n",
    "    try:\n",
    "        return parse_model_response(raw_response, model_type)\n",
    "    except ValueError as error:\n",
    "        if budget.remaining <= 0:\n",
    "            raise RuntimeError(f\"JSON 校验失败且没有剩余调用次数:{error}\") from error\n",
    "        repair_prompt = (\n",
    "            \"上一次响应无法通过 JSON 校验。不要改变内容含义,只修复格式。\\n\"\n",
    "            f\"校验错误:{error}\\n\"\n",
    "            f\"原响应:\\n{raw_response}\\n\"\n",
    "            f\"目标 Schema:\\n{schema}\\n\"\n",
    "            \"只返回修复后的 JSON。\"\n",
    "        )\n",
    "        repaired_response = budget.run(agent, repair_prompt)\n",
    "        return parse_model_response(repaired_response, model_type)\n",
    "\n",
    "\n",
    "# 创建 MinutesAgent 和 ReviewAgent。\n",
    "def build_agents():\n",
    "    llm = HelloAgentsLLM()\n",
    "    minutes_agent = SimpleAgent(name=\"MinutesAgent\", llm=llm, system_prompt=MINUTES_SYSTEM_PROMPT)\n",
    "    review_agent = SimpleAgent(name=\"ReviewAgent\", llm=llm, system_prompt=REVIEW_SYSTEM_PROMPT)\n",
    "    return minutes_agent, review_agent\n"
   ]

View on GitHub (pinned to 606a07d341)

Solutions

  1. Read the chained error (raise ... from error) to see the exact parse failure — fix that root cause (schema in prompt, JSON-only instruction, larger max_tokens) rather than just adding calls.
  2. Raise or split budgets: CallBudget(maximum=6), or one budget per agent stage.
  3. Capture the raw failing response in the except block (log raw_response) so you can see what the model actually returned.
  4. For production, prefer the provider's structured-output/JSON mode over prompt-and-repair loops.

Example fix

# before
except ValueError as error:
    if budget.remaining <= 0:
        raise RuntimeError(f"JSON 校验失败且没有剩余调用次数:{error}") from error

# after
except ValueError as error:
    print(f"parse failed; raw response:\n{raw_response}")
    if budget.remaining <= 0:
        raise RuntimeError(f"JSON 校验失败且没有剩余调用次数:{error}") from error
# plus: CallBudget(maximum=6) and schema-in-prompt as in run_structured
Defensive patterns

Strategy: retry

Validate before calling

# preflight: budget must have headroom for one repair before parsing
if budget.remaining < 2:
    raise RuntimeError("insufficient budget for parse + repair")

Type guard

null

Try / catch

try:
    return parse_model_response(raw, model_type)
except ValueError as error:
    log_raw_response(raw)  # capture evidence
    if budget.remaining <= 0:
        raise RuntimeError("exhausted; re-run with larger budget") from error
    return parse_model_response(budget.run(agent, repair_prompt(raw, error)), model_type)

Prevention

When it happens

Trigger: The final budgeted call returns invalid JSON (truncated, prose-wrapped, schema-mismatched after slicing) and budget.remaining is already 0 — commonly because earlier stages (draft + review + prior repairs) consumed the 4-call cap. Note it fires on the parse failure path only; a healthy parse never reaches it even at remaining=0.

Common situations: Weak JSON prompting causing a repair loop that exhausts CallBudget before producing valid JSON; max_tokens truncation chopping the closing brace; high temperature producing free-form answers; budget shared across multiple agents so a repair-starved stage hits this on its first failure.

Related errors


AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14). Data as JSON: /api/errors/cc79f7150f9c5a3a. Report an issue: GitHub.