BUG-HUNT: [consistency] CostBudgetService.record_plan_cost() silently skips warning threshold check #7327

Open
opened 2026-04-10 16:55:56 +00:00 by HAL9000 · 0 comments
Owner

Bug Report: Consistency — Budget Warning Not Emitted on Cost Recording

Severity Assessment

  • Impact: When record_plan_cost() is called directly (without first calling check_budget_hierarchy()), the budget warning threshold crossing is never detected and BUDGET_WARNING events are never emitted. Users can silently exceed 80% of their budget with no notification.
  • Likelihood: Medium — any code path that records cost without first checking (e.g. background cost accumulation, test setups) will miss the warning
  • Priority: Medium

Location

  • File: src/cleveragents/application/services/cost_budget_service.py
  • Function/Class: CostBudgetService.record_plan_cost()
  • Lines: 273–300

Description

The CostBudgetService has two separate code paths:

  1. check_budget_hierarchy() — checks limits AND calls _check_warning() before the cost is recorded
  2. record_plan_cost() — records the cost but NEVER calls _check_warning()

The _check_warning() call (line 269) is only in check_budget_hierarchy(), making the warning system dependent on callers always invoking check_budget_hierarchy before record_plan_cost. If a caller records cost without checking first, or if costs are accumulated through a different code path, the warning threshold is silently crossed without a BUDGET_WARNING event.

Evidence

# cost_budget_service.py lines 273-300
def record_plan_cost(self, session_id: str, cost: float) -> None:
    """Record a cost against the session (and its org if linked)."""
    ...
    with self._lock:
        session_budget = self._sessions.get(session_id)
        if session_budget is not None:
            session_budget.record_cost(cost)   # ← cost recorded

        org_id = self._session_org.get(session_id)
        if org_id is not None:
            org_acc = self._orgs.get(org_id)
            if org_acc is not None:
                org_acc.record_cost(cost)      # ← org cost recorded
    # ← No call to _check_warning() — warning threshold never checked here!

Compare with check_budget_hierarchy() (line 269):

# --- Warning check ---
warning = self._check_warning(session_id)  # ← only here, not in record_plan_cost

Expected Behavior

record_plan_cost() should check if the budget warning threshold has been crossed after recording the cost, and emit BUDGET_WARNING if so.

Actual Behavior

record_plan_cost() records the cost silently without checking the warning threshold.

Suggested Fix

Add a warning check at the end of record_plan_cost():

def record_plan_cost(self, session_id: str, cost: float) -> None:
    ...
    with self._lock:
        session_budget = self._sessions.get(session_id)
        if session_budget is not None:
            session_budget.record_cost(cost)
        org_id = self._session_org.get(session_id)
        if org_id is not None:
            org_acc = self._orgs.get(org_id)
            if org_acc is not None:
                org_acc.record_cost(cost)
        # Check warning threshold after recording cost
        self._check_warning(session_id)

Category

consistency

TDD Note

After this bug issue is verified, a corresponding Type/Testing issue will be created for TDD. The test will use tags: @tdd_issue, @tdd_issue_<this-issue-number>, and @tdd_expected_fail to prove the bug exists before fixing it.


Automated by CleverAgents Bot
Supervisor: Bug Detection Pool | Agent: bug-hunt-pool-supervisor

## Bug Report: Consistency — Budget Warning Not Emitted on Cost Recording ### Severity Assessment - **Impact**: When `record_plan_cost()` is called directly (without first calling `check_budget_hierarchy()`), the budget warning threshold crossing is never detected and `BUDGET_WARNING` events are never emitted. Users can silently exceed 80% of their budget with no notification. - **Likelihood**: Medium — any code path that records cost without first checking (e.g. background cost accumulation, test setups) will miss the warning - **Priority**: Medium ### Location - **File**: `src/cleveragents/application/services/cost_budget_service.py` - **Function/Class**: `CostBudgetService.record_plan_cost()` - **Lines**: 273–300 ### Description The `CostBudgetService` has two separate code paths: 1. `check_budget_hierarchy()` — checks limits AND calls `_check_warning()` before the cost is recorded 2. `record_plan_cost()` — records the cost but NEVER calls `_check_warning()` The `_check_warning()` call (line 269) is only in `check_budget_hierarchy()`, making the warning system dependent on callers always invoking `check_budget_hierarchy` before `record_plan_cost`. If a caller records cost without checking first, or if costs are accumulated through a different code path, the warning threshold is silently crossed without a `BUDGET_WARNING` event. ### Evidence ```python # cost_budget_service.py lines 273-300 def record_plan_cost(self, session_id: str, cost: float) -> None: """Record a cost against the session (and its org if linked).""" ... with self._lock: session_budget = self._sessions.get(session_id) if session_budget is not None: session_budget.record_cost(cost) # ← cost recorded org_id = self._session_org.get(session_id) if org_id is not None: org_acc = self._orgs.get(org_id) if org_acc is not None: org_acc.record_cost(cost) # ← org cost recorded # ← No call to _check_warning() — warning threshold never checked here! ``` Compare with `check_budget_hierarchy()` (line 269): ```python # --- Warning check --- warning = self._check_warning(session_id) # ← only here, not in record_plan_cost ``` ### Expected Behavior `record_plan_cost()` should check if the budget warning threshold has been crossed **after** recording the cost, and emit `BUDGET_WARNING` if so. ### Actual Behavior `record_plan_cost()` records the cost silently without checking the warning threshold. ### Suggested Fix Add a warning check at the end of `record_plan_cost()`: ```python def record_plan_cost(self, session_id: str, cost: float) -> None: ... with self._lock: session_budget = self._sessions.get(session_id) if session_budget is not None: session_budget.record_cost(cost) org_id = self._session_org.get(session_id) if org_id is not None: org_acc = self._orgs.get(org_id) if org_acc is not None: org_acc.record_cost(cost) # Check warning threshold after recording cost self._check_warning(session_id) ``` ### Category consistency ### TDD Note After this bug issue is verified, a corresponding Type/Testing issue will be created for TDD. The test will use tags: `@tdd_issue`, `@tdd_issue_<this-issue-number>`, and `@tdd_expected_fail` to prove the bug exists before fixing it. --- **Automated by CleverAgents Bot** Supervisor: Bug Detection Pool | Agent: bug-hunt-pool-supervisor
HAL9000 added this to the v3.5.0 milestone 2026-04-10 19:05:43 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
cleveragents/cleveragents-core#7327
No description provided.