[MODEL] Claude deployed an unattended job calling a metered paid API with no cost guardrails — $411 in unintended charges

Status Open
Maintainer reply None cached
Activity 1 comment · opened Aug 6, 2026

Preflight Checklist

  • [x] I have searched existing issues for similar behavior reports
  • [x] This report does NOT contain sensitive information (API keys, passwords, etc.)

Type of Behavior Issue

Other unexpected behavior

What You Asked Claude to Do

Build a lesson-audio transcription feature for my Spanish-tutoring platform
using Google Cloud Speech-to-Text: capture audio during lessons, transcribe it,
and store transcripts for tutors to review. Built and deployed to my staging
environment across several sessions.

What Claude Actually Did

Claude wrote the feature and registered it as a cron job running every 5 minutes
on staging. The code had a bug: when a transcription attempt failed, nothing
recorded the failure, so the job re-submitted the same audio clip to the paid
Speech-to-Text API every 5 minutes for ~5 days, until the record aged out of the
job's query window on its own.

At no point was the cost exposure of an unattended, recurring, per-call-billed
API job raised — no cap, no rate limit, no circuit breaker, no spend alert, and
no note that this would fire 288 times a day. Nothing self-halted; it stopped by
accident.

Result: $411.79 in Google Cloud charges (Speech-to-Text $341.74, Cloud Storage
egress $67.20) on a staging environment with zero real users, discovered 8 days
later via a bank statement. Google declined a credit — their one-time lifetime
goodwill exception had been used in 2017 for an unrelated incident.

Expected Behavior

Before deploying a scheduled job that calls a metered, per-invocation paid API,
Claude should have:

  1. Explicitly flagged the cost model — "this calls a paid API and will fire 288

times/day unattended" — the same way destructive commands get called out.

  1. Proposed a guardrail as part of the original implementation, not after an

incident: a daily call ceiling, a circuit breaker, or a hard cap.

  1. Wired up cost visibility at deploy time (alert/notification/log) so a runaway

loop is visible in hours, not on a bank statement 8 days later.

  1. Treated the unbounded retry path as a cost defect, not just a correctness

defect. "This can fail and will be retried forever" is a spend bug when the
retry target bills per call.

After the incident we added exactly this: a 20-calls/day circuit breaker plus a
Slack notification on every real API call. It took ~10 minutes. Had it been there
from the start, this would have been a ~$1 incident that alerted me same-day.

Files Affected

All on my own staging server (PHP/Laravel app), written by Claude:

- app/Console/Commands/TranscribeLessons.php    (the recurring job)
- app/Console/Kernel.php                        (registered ->everyFiveMinutes())
- app/Services/LessonTranscriptionService.php   (unbounded retry bug lived here)
- app/LessonTranscription.php                   (model)
- app/Http/Controllers/LessonController.php     (related transcription endpoint)
- lib/lesson-audio-capture.js
- lib/GcsSignedUrl.php

No unexpected file access — this isn't a file-scope issue. Listed for context on
what was built.

Permission Mode

Accept Edits was ON (auto-accepting changes)

Can You Reproduce This?

No, only happened once

Steps to Reproduce

Not a deterministic repro — this was a single incident. The general shape:

  1. Ask Claude to build a feature that calls a metered, per-invocation cloud API.
  2. Let it deploy that work and register it on a recurring schedule (cron /

Laravel scheduler) in a non-production environment.

  1. Observe that no cost ceiling, rate limit, circuit breaker, or spend alert is

proposed at any point, and that a failure path with no terminal state will
retry indefinitely against the paid API.

Claude Model

Sonnet

Relevant Conversation

The feature was built across a long multi-session engagement. At no point in
building or deploying the recurring job was cost exposure raised — not as a
warning, not as a suggestion, not as a question. The omission is the issue, so
there isn't a single quotable line; it's the absence of one.

For contrast, after I flagged the charge, Claude diagnosed the root cause,
disabled the job, fixed the retry bug, and added a circuit breaker plus Slack
alerting within about 15 minutes. The capability was clearly there — it just
wasn't applied proactively.

Impact

High - Significant unwanted changes

Claude Code Version

1.25927.0 (Claude desktop app)

Platform

Anthropic API

Additional Context

  • The environment was staging with zero real users, which is exactly why nobody

was watching it. Non-production is arguably where this failure mode is most
likely and least likely to be caught.

  • Detection took 8 days and only happened because the charge appeared on a

company bank statement.

  • Note on this form: there's no "Type of Behavior Issue" category for an action

with real financial cost. I selected "Other unexpected behavior." That gap may
itself be worth closing.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗