calesthio/OpenMontage · warning · ApprovalRequiredError
First paid use of tool {entry['tool']!r} requires approval
Error message
First paid use of tool {entry['tool']!r} requires approval What it means
ApprovalRequiredError raised by CostTracker.reserve when require_approval_for_new_paid_tool is enabled, the entry has estimated_usd > 0, and the tool name is not in _approved_tools. It enforces an explicit opt-in the first time any paid tool is used, independent of amount. Once approve_tool(tool) is called the name is persisted in approved_tools and later reserves succeed.
Source
Thrown at tools/cost_tracker.py:138
Raises BudgetExceededError in cap mode, or ApprovalRequiredError
when the action exceeds the single-action approval threshold.
"""
entry = self._find(entry_id)
estimated = entry["estimated_usd"]
# Check single-action approval threshold
if estimated > self.single_action_approval_usd:
if self.mode != BudgetMode.OBSERVE:
raise ApprovalRequiredError(
f"Action costs ${estimated:.2f}, exceeds "
f"single-action threshold ${self.single_action_approval_usd:.2f}"
)
# Check new paid tool approval
if self.require_approval_for_new_paid_tool and estimated > 0:
if entry["tool"] not in self._approved_tools:
if self.mode != BudgetMode.OBSERVE:
raise ApprovalRequiredError(
f"First paid use of tool {entry['tool']!r} requires approval"
)
# Check budget
if estimated > self.usable_budget_usd:
message = (
f"Reservation of ${estimated:.2f} exceeds usable budget "
f"${self.usable_budget_usd:.2f}"
)
if self.mode == BudgetMode.CAP:
raise BudgetExceededError(message)
if self.mode == BudgetMode.WARN:
entry["budget_warning"] = True
entry["budget_warning_message"] = message
entry["status"] = EntryStatus.RESERVED.value
entry["reserved_usd"] = estimated
entry["timestamp"] = self._now()View on GitHub (pinned to 95e1c3d0ab)
Solutions
- Approve the tool once via tracker.approve_tool(entry['tool']) (it persists to the cost log) and retry reserve().
- Pre-populate approved_tools in the budget/cost-log config for tools you know are sanctioned.
- Disable require_approval_for_new_paid_tool if per-tool gating is not wanted.
- Run in OBSERVE mode for exploratory sessions where approvals should not block.
Example fix
# before
tracker.reserve(entry_id) # first paid use of 'kling_tts' -> ApprovalRequiredError
# after
if entry["tool"] not in tracker._approved_tools:
tracker.approve_tool(entry["tool"])
tracker.reserve(entry_id) Defensive patterns
Strategy: validation
Validate before calling
def tool_approved(tracker, tool: str) -> bool:
return tool in tracker._approved_tools Try / catch
from tools.cost_tracker import ApprovalRequiredError
try:
tracker.reserve(entry_id)
except ApprovalRequiredError as e:
if "requires approval" in str(e):
tracker.approve_tool(tool_name)
tracker.reserve(entry_id) Prevention
- Pre-approve known-good tools right after tracker initialization.
- Persist the cost log so approved_tools survives restarts.
- Wrap reserve() in a helper that auto-handles first-use approval if policy allows.
When it happens
Trigger: reserve() on the first paid entry for a tool with require_approval_for_new_paid_tool=True and mode != OBSERVE. Every new provider/tool (new image model, new TTS engine) triggers it once until approved.
Common situations: Fresh projects or fresh cost logs where approved_tools is empty; adding a new tool to a workflow after initial setup; loading an old cost log that predates the tool.
Related errors
- Action costs ${estimated:.2f}, exceeds single-action thresho
- Reservation of ${estimated:.2f} exceeds usable budget ${self
- Cost entry {entry_id!r} not found
- pricing is unknown for a custom Ark Endpoint/Model; set cust
AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15).
Data as JSON: /api/errors/690ccc2abd8f817b.
Report an issue: GitHub.