Scan your codebase for fragile API calls and find out how many failures you're shipping to production every month.
Most third-party APIs run at ~99.5% uptime. That's ~3.6 hours of outage per month. Every fetch() in your codebase without a timeout, retry, try/catch, or fallback turns those outages into user-visible failures.
flake-tax scans your codebase, finds every external API call, inspects the surrounding code for reliability protections, and tells you exactly how many failures you're leaking to users.
npx flake-tax ./srcNo install. No config. No signup.
- Scans
.ts,.tsx,.js,.jsx,.mjs,.mts,.pyfiles forfetch(),axios,requests,httpxcalls to external URLs - Inspects each call's enclosing function for reliability smells:
- no timeout → hung requests → user sees a spinner forever
- no retry → transient blips become hard failures
- no try/catch → errors crash the request handler
- no fallback → no graceful degradation
- no circuit breaker → one slow upstream cascades through your stack
- Scores each call from 0 (fully protected) to 100 (completely naked)
- Projects user-visible failures per month based on call volume and industry-average 99.5% API uptime
╔═══════════════════════════════════════╗
║ 🪢 flake-tax ║
╚═══════════════════════════════════════╝
═════════════════════════════════════════════════════════════════
FLAKE TAX REPORT
═════════════════════════════════════════════════════════════════
API calls scanned: 9
Avg fragility: 94/100
Severity: 8 critical 1 risky 0 okay
Per-Call Breakdown
────────────────────────────────────────────────────────────
CRITICAL GET https://github.com/login/oauth/access_token
./server/_core/sdk.ts:30
████████████████████ 100/100 fragility │ 150 user-visible fails/month
✗ timeout ✗ retry ✗ try/catch ✗ fallback ✗ circuit breaker
CRITICAL GET https://api.github.com/user
./server/_core/sdk.ts:57
████████████████████ 100/100 fragility │ 150 user-visible fails/month
✗ timeout ✗ retry ✗ try/catch ✗ fallback ✗ circuit breaker
RISKY GET https://urlhaus-api.abuse.ch/v1/url/
./server/threatShield.ts:143
██████████░░░░░░░░░░ 50/100 fragility │ 75 user-visible fails/month
✓ timeout ✗ retry ✓ try/catch ✗ fallback ✗ circuit breaker
Projected Failures (at 99.5% API uptime, 1000 calls/day per endpoint)
────────────────────────────────────────────────────────────
1,275 user-visible failures per month
= 43/day, 2/hour
MOST COMMON no retry (9/9 calls)
WORST OFFENDER GET https://github.com/login/oauth/access_token
100/100 — projected 150 user-visible failures/month
npx flake-tax ./src # scan a directory
npx flake-tax . # scan current directory
npx flake-tax ./src --calls 5000 # 5000 calls/day per endpoint
npx flake-tax ./src --uptime 0.99 # assume 99% upstream uptime (flaky)
npx flake-tax ./src --uptime 0.999 # assume 99.9% upstream uptime (gold tier)
npx flake-tax ./src --json > report.json # output as JSONEach missing protection adds to the call's fragility score:
| Protection missing | Weight |
|---|---|
| try/catch | +30 |
| retry | +25 |
| timeout | +20 |
| fallback | +15 |
| circuit breaker | +10 |
A call with zero protection scores 100 (critical). A call wrapped in pRetry() with a timeout, try/catch, and fallback scores 10 (okay).
base_fails_per_month = calls_per_day * 30 * (1 - upstream_uptime)
user_fails_per_month = base_fails * (fragility_score / 100)
At the default 99.5% uptime / 1000 calls/day, a fully-naked call (100/100) leaks 150 failures/month to users. A fully-protected call (0/100) leaks 0.
| Protection | Detection patterns |
|---|---|
| timeout | signal:, AbortSignal.timeout(), new AbortController, timeout: 5000, Python timeout=5 |
| retry | pRetry(), @retry, @backoff.on_exception, retry loops, axios-retry, got, ky |
| try/catch | surrounding try/catch block, .catch(), Python try/except |
| fallback | catch block returning a default, ?? default, || default, Python except: return None |
| circuit breaker | opossum, cockatiel, pybreaker, circuitbreaker |
Detection is intentionally local (scoped to the enclosing function) so protections on sibling calls don't falsely credit yours.
The fragility flake-tax reveals is exactly what SelfHeal fixes.
Proxy your external API calls through SelfHeal and get retries, timeouts, circuit breakers, and fallbacks — without touching your request code. x402 pay-per-heal pricing: you're only charged when SelfHeal saves a request that would have failed.
# Before
const res = await fetch("https://api.flaky-service.com/data");
# After — one line change, now has retry + circuit breaker + timeout
const res = await fetch("https://selfheal.dev/api/x402/proxy", {
method: "POST",
body: JSON.stringify({
url: "https://api.flaky-service.com/data",
method: "GET",
}),
});- Call succeeds first try? Free.
- SelfHeal retried and saved it? $0.001 USDC. Only charged when it delivers value.
flake-taxnever sends your code anywhere. It does all analysis locally.- It does not hit any of the URLs it finds — pure static analysis.
- No tracking, no telemetry, no signup.
- Only detects external URLs (starting with
http://orhttps://). Relative URLs likefetch("/api/...")are skipped — those are your own same-origin endpoints, and SelfHeal doesn't help with those anyway. - Template URLs like
fetch(`${baseUrl}/path`)are skipped. flake-tax only inspects concrete string literals. - Documentation code examples inside template strings may register as fetch calls. Review the file paths — if they're under
docs/,examples/, or similar, you can ignore them.
MIT
Built by Freedom Engineers