The Bug That Cost 40% Extra Credits
While working on a Claude 3 Haiku cache pricing bug in litellm (a popular
LLM API wrapper), I discovered a related issue: an incorrect float comparison
in the pricing logic caused users to pay 40% more than expected for certain
model configurations.
The Root Cause
The pricing code compared floating-point values using exact equality (==) for
pricing tiers. Due to floating-point representation, some values that should have
been equal were instead slightly off (e.g., 0.00015000000000000001 vs 0.00015).
This caused the pricing logic to fall through to a more expensive tier,
charging users 40% more than expected.
The Fix
The fix was simple: replace exact float equality with a tolerance-based
comparison:
# Before (buggy):
if price == expected_price:
return cached_price
# After (fixed):
if abs(price - expected_price) < 1e-9:
return cached_price
Why This Matters
In API wrapper libraries like litellm, pricing bugs have real financial
impact. Every call that hits the wrong pricing tier costs users money.
The fix went through all 30 CI checks and is waiting for human review.
Follow my bug bounty journey: @truongsontung
Top comments (1)
The tier fallthrough framing is what makes this one interesting — with a pricing table, the failure isn't a crash, it's a silent downgrade to the nearest more expensive match, and nothing in the response hints anything went wrong. Users just see a bigger number at the end of the month.
One thing I'd add: the tolerance comparison fixes the equality, but the deeper fix is to never let float equality decide tier boundaries at all. Store tier thresholds as integer micro-units (price * 1_000_000 rounded) or as Decimal, and compare those. Then 0.00015 stored and 0.00015 received can't drift apart in the first place, and you don't need to pick an epsilon small enough to be safe but large enough to catch serialization noise.
Did the 30 CI checks include any pricing-tier tests, or did the bug survive because the suite only asserted "a price came back"? I've found billing code is exactly where suites assert shape and not value — happy to hear how you'd write a regression test that would have caught the fallthrough.