datawhalechina/hello-agents · error · RuntimeError

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

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.

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.

Appendix: 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)