When things break
Each section below starts with a symptom you can search for. If none of these fix it, email support@swing-deck.com with the relevant log file attached.
Install issues
"Python 3 not found" on launch (macOS / Windows)
You don't have Python installed, or it's not on PATH. Fix:
- Download Python 3.11+ from python.org/downloads.
- Windows users: make sure "Add Python to PATH" is checked during install.
- Verify in terminal:
python3 --version(macOS) orpy --version(Windows). - Re-launch Swing Deck.
"SwingDeck.app can't be opened because it's from an unidentified developer" (macOS)
Beta builds are unsigned. Right-click the app in Finder → Open. Confirm the warning once. After that, normal double-click works. Production builds will be signed and notarized.
SmartScreen blocks the installer (Windows)
Beta installers aren't code-signed yet. Click More info → Run anyway. Production builds will use an EV code-signing cert that bypasses SmartScreen.
"pip install -r requirements.txt" fails on numpy / pandas
This is almost always a compiler mismatch. On macOS arm64:
pip install --upgrade pip setuptools wheel
arch -arm64 python3 -m pip install -r requirements.txt
On Windows with Python 3.13+, you may need the wheel for ta-lib; install the Microsoft C++ Build Tools if pip asks.
Audit not running
Dashboard loads but all scores are blank / "—"
The audit has never run for the current ticker set. Three things to check:
- Is
portfolio.txtpopulated?cat portfolio.txt— should show one ticker per line. - Is the audit process running? In the dashboard, open Control panel (top-right ⚙) — the "Audit" chip should be green. If red, click ▶ Start.
- Manual trigger: run
python3 audit_framework.pyfrom the repo root. You should see progress bars and eventually "✓ audit_output.json written".
Audit hangs or repeatedly fails
Most likely a data-provider rate limit. Check audit_dashboard.log for one of:
yfinance 429— Yahoo rate-limit. Add Finnhub / Alpha Vantage keys to.envto fall through to Tier 1 providers.Connection reset by peer— transient network. The retry loop will recover within 2-3 cycles.KeyError: 'closes'— malformed audit_output.json from a previous failed run. Deleteaudit_output.jsonand re-run.
"LICENSE LIMIT: FREE tier allows 5 portfolio tickers" warning
Exactly what it says — you have more tickers than your tier allows. The audit silently drops the extras. Upgrade or reduce the list.
License won't activate
"Invalid format — expected SWING-XXXX-XXXX-XXXX"
Paste the key exactly as received — all uppercase, dashes included. No leading/trailing whitespace. The Activate button only fires when the format regex matches.
"License key not found" after pasting a real key
Three causes:
- Typo — copy from your email, don't retype.
Ovs0,Ivs1are the usual suspects. - Network — the local app couldn't reach
api.swing-deck.com. Check status.swing-deck.com. - Billing failed — the Stripe webhook never completed, so no license row was created. Check your email for a Stripe receipt; if no receipt, the payment never went through.
Tier shows TRIAL but features say FREE
Your trial expired. Check Settings → License — if status shows expired, upgrade at pricing or email support for a trial extension.
License validates online but loses features offline
The local cache has a 7-day grace period. If you've been offline longer than 7 days, features drop until you reconnect. Workaround: set your system clock back? No. Just get on wifi for 10 seconds — the validate call is sub-second.
Broker errors
E*Trade "unauthorized" on every call
Your OAuth tokens expired (they're single-day — midnight ET). Delete etrade_tokens.json and restart control_server.py. You'll re-auth via browser on the first broker call.
Positions show in E*Trade but not Swing Deck
Usually wrong account ID. Grab the account ID from the E*Trade portfolio URL — it's the long numeric string — and set it as ETRADE_ACCOUNT_ID in .env. Restart the server.
"Broker writes require a Pro or Premium license" (403)
Free tier cannot place or modify orders. Either upgrade or run in paper trading mode (always available, no broker needed).
Raise-Stop request fails with "parity mismatch"
Our logged stop differs from what E*Trade thinks is active. Usually because you moved the stop manually in E*Trade's UI while the dashboard was running. Refresh the dashboard (↺ Refresh button) to resync, then retry.
Circuit breaker tripped
3 consecutive broker failures in a short window triggered the safety breaker. No new writes will be sent for 30 minutes. To reset manually:
curl -X POST http://localhost:8001/broker/circuit/reset \
-H "X-CSRF-Token: $(curl -s http://localhost:8001/csrf-token | jq -r .token)"
But first: check broker_orders.log to find out why it tripped. Don't reset blindly.
Alerts not arriving
"Send test alert" succeeds but no email/push arrives
Common causes in order of likelihood:
- Spam folder — first-time senders frequently land here. Mark as "not spam" and add
alerts@swing-deck.comto your contacts. - Your email address on file — if you signed up with
foo@bar.combut are using Gmail now, check the original inbox. Manage via Settings → License → Manage subscription. - Resend bounce — a previous email to you bounced and Resend suppressed the address. Email support with your current address and we'll clear the suppression.
Alerts used to fire, stopped firing
Check Settings → Alerts:
- Is the engine running? The status chip should be green.
- Are alert types toggled on? Uncheckting "score_drop" disables it silently.
- Within the 4-hour dedup window, the same alert won't fire twice. Check Recent alerts — it may already have fired.
Getting too many alerts
Raise the score-drop threshold in Settings → Alerts (default 10; try 15 or 20). Or disable specific alert types you don't care about. Changes apply on the next 60-second tick.
Sync issues
"Passphrase doesn't match" on restore
The fingerprint check caught a mistyped passphrase. Retype it carefully. If you've rotated passphrases since this snapshot was made, the old snapshot is undecryptable — this is by design. We can't reset your passphrase because we never had it.
"Backup too large" (5 MB cap)
Typical backups are 50-200 KB. If yours is 5 MB+, something is wrong. Check cloud_sync_staged_localstorage.json — if it's huge, prune large objects from localStorage (journal with > 10 000 entries, e.g.) before retrying.
Restore succeeds but positions still missing
The dashboard needs a hard reload after a restore. Settings → Sync → Restore flow auto-reloads, but if something interrupted it, hit Cmd-Shift-R (macOS) or Ctrl-F5 (Windows).
Finding the logs
When you email support, include the relevant file:
| Log | Path | What's in it |
|---|---|---|
| audit_dashboard.log | repo root | Main server log — audit runs, HTTP requests, errors |
| broker_orders.log | repo root | Every broker-write attempt, preview/place, errors |
| macOS server.log | ~/Library/Logs/SwingDeck/ | Launcher output (if using .app bundle) |
| Windows server.log | %LOCALAPPDATA%\SwingDeck\logs\ | Launcher output (if using .exe) |
| Browser console | F12 / right-click → Inspect | Dashboard JS errors, network failures |
grep -v "SWING-\|_KEY=" over the file, or at minimum scrub by hand.
Still stuck?
Email support@swing-deck.com with:
- What you were trying to do
- What happened instead
- Your OS and Swing Deck version (shown as
v4.3in the top-left) - Relevant log snippet (redacted per above)