Skip to main content

max / balanced_breakfast

5.0 KB · 111 lines History Blame Raw
1 # Troubleshooting — Balanced Breakfast
2
3 ## Plugin Fetch Failures
4
5 **Symptoms:** Feed shows yellow (degraded) or red (circuit broken) status.
6
7 ### Error Categories
8
9 | Category | Causes | Auto-Retry | Circuit Break |
10 |----------|--------|-----------|---------------|
11 | **Transient** | DNS timeout, HTTP 500/502/503 | Yes | After 10 failures |
12 | **RateLimited** | HTTP 429 | Yes (after delay) | Never |
13 | **Auth** | HTTP 401/403, invalid API key | No | Immediate |
14 | **Config** | HTTP 404/410, bad URL, missing field | No | Immediate |
15 | **Parse** | Malformed RSS/JSON/XML | Yes | After 10 failures |
16
17 ### Decision Tree
18
19 1. **Feed shows red (circuit broken)?**
20 - Check `last_error` in feed details for the error category
21 - **Auth error** → Fix API key/credentials in feed config, then "Reset & Retry"
22 - **Config error** → Verify feed URL exists and is accessible, delete and re-add
23 - **10+ transient failures** → Wait for service recovery, then "Reset & Retry"
24
25 2. **Feed shows yellow (degraded)?**
26 - System retries automatically
27 - If persistent: verify URL, check API key, try manual retry
28
29 3. **Feed never updates?**
30 - Plugin `.rhai` file missing from `plugins/` → restart app
31 - Auto-fetch disabled → check settings
32 - Circuit breaker tripped → see above
33
34 ## Circuit Breaker
35
36 - **Threshold:** 10 consecutive failures for transient/parse errors. Auth/config errors trip immediately.
37 - **Rate-limited errors** do NOT increment the failure counter.
38 - **Reset:** Feed menu → "Reset & Retry" (calls `reset_circuit_breaker_and_fetch`)
39 - **What reset does:** Sets `circuit_broken=false`, `consecutive_failures=0`, clears `last_error`, attempts fresh fetch
40
41 ## OPML Import Issues
42
43 | Symptom | Cause | Fix |
44 |---------|-------|-----|
45 | "Invalid OPML: ..." | Malformed XML | Validate OPML syntax (must be valid XML with `<outline>` elements) |
46 | URLs skipped | Non-http/https URLs in OPML | Edit OPML to use only http/https URLs |
47 | Feeds already exist | Duplicate URLs | Expected — `skipped` counter shows how many were duplicates |
48 | Import result shows errors | Database or URL validation failures | Check error messages in import result, fix individual URLs |
49
50 **Import result format:** `{ imported: N, skipped: N, errors: [...] }`
51
52 ## Secret Decryption Failures
53
54 **Symptoms:** Feeds with API keys show auth errors despite correct credentials.
55
56 **Encryption scheme:** AES-256-GCM, format `bb_enc:v1:<base64(nonce || ciphertext || tag)>`
57
58 | Symptom | Cause | Fix |
59 |---------|-------|-----|
60 | Feed auth errors after OS reinstall | Encryption key lost from keychain | Delete feeds, re-add with credentials (auto-encrypts on save) |
61 | "Decryption failed" in logs | Wrong key or corrupted ciphertext | Delete `~/.config/balanced-breakfast/encryption.key`, restart (generates new key). Re-add feeds. |
62 | Keychain unavailable | macOS Keychain locked, Linux Secret Service not running | Unlock keychain or start D-Bus Secret Service |
63
64 **Key storage priority:**
65 1. OS keychain (macOS Keychain, Windows Credential Manager, Linux Secret Service)
66 2. Fallback: `~/.config/balanced-breakfast/encryption.key` (file, 0600 permissions)
67
68 **Backward compatibility:** Unencrypted secret values pass through on decrypt and get encrypted on next config change.
69
70 ## Plugin Sandbox Violations
71
72 | Error | Limit | Fix |
73 |-------|-------|-----|
74 | "Script execution exceeded operation limit" | 100,000 operations per fetch | Plugin has infinite loop or very inefficient logic |
75 | "Max recursion level exceeded" | 32 call levels | Refactor plugin to iterative approach |
76 | "HTTP request limit exceeded" | 100 requests per fetch | Plugin making too many HTTP calls |
77 | "Fetch timeout exceeded" | 60s aggregate per fetch | Plugin spending too long overall |
78 | "Blocked request to internal address" | localhost/private IPs blocked | Plugin trying SSRF — use public URLs only |
79
80 **Per-request timeout:** 15 seconds. **Response size limit:** 2 MB.
81
82 ## Database Issues
83
84 **Database location:** `~/.local/share/balanced-breakfast/` (platform-dependent), SQLite via sqlx.
85
86 | Symptom | Fix |
87 |---------|-----|
88 | App won't start, migration error | Delete DB file, restart (fresh DB, re-sync from cloud) |
89 | "database is locked" | Close other app instances, exclude DB from antivirus |
90 | FTS5 search returns no results | Rebuild FTS index: delete `feed_items_fts` table, restart app |
91
92 ## Sync Issues
93
94 Same SyncKit integration as GoingsOn:
95 - Credentials stored in OS keychain
96 - Push/pull with changelog triggers
97 - `applying_remote` flag can get stuck — restart app to clear
98 - Sync interval: 15 minutes (configurable)
99
100 **What syncs:** Feed subscriptions, feed tags, user config, query feeds, item read/star state. Item content does NOT sync (fetched independently per device).
101
102 ## Error Codes
103
104 | Code | Meaning |
105 |------|---------|
106 | `BAD_REQUEST` | Invalid input (bad OPML, missing field) |
107 | `NOT_FOUND` | Feed or resource doesn't exist |
108 | `DATABASE` | SQLite error |
109 | `INTERNAL` | Unexpected error |
110 | `PLUGIN` | Rhai plugin error (sandbox violation, runtime error) |
111