Troubleshooting Guide
This page reflects the current desktop/mobile architecture in v0.1.1.
Before You Debug
Start by deciding which surface is actually failing:
- desktop hub
- iPhone companion
- remote route
- buyer/download/license flow
Connectivity
Mobile or remote client gets 401 Unauthorized
This usually means the client is trying to use protected /api/* routes without a valid bearer token.
What to do:
- Re-open the latest desktop QR instead of reusing an old remote URL.
- If the desktop shows
pairing_not_armed, arm pairing again before reconnecting. - On mobile, disconnect and reconnect so the app can pair again or refresh auth state.
Remote playback fails with a license-related message
This is different from a normal network error.
What to check:
- The desktop hub has an active license state for remote access.
- The hub can still validate or reuse its signed entitlement state.
- You are not testing remote while expecting LAN-only behavior.
QR returns 409 pairing_not_armed
This is expected when a remote route exists but the desktop has not armed pairing yet.
What to do:
- Open the desktop app locally.
- Arm pairing from the remote/connect settings flow.
- Refresh the QR and rescan it.
Files or /api/browse returns 401, 403, or Forbidden
The folder browser is a protected route for remote callers.
What to do:
- Make sure the client is paired and has a fresh bearer token.
- Reconnect from the QR if the auth state is stale.
- Confirm the folder still exists on disk.
If the phone was already paired and public web access is set to Shared pages only, /api/browse should still work for that paired phone. A new 403 there usually means the mobile private-access path regressed, not that the remote route itself is missing.
Mobile cannot reach the hub locally
What to check:
- The desktop hub is running on
38472. - Both devices are on the same network if you are not using Cloudflare or Tailscale.
- The desktop host is reachable at
YOUR_IP:38472. - Firewall rules are not blocking the app.
Helpful local checks:
curl http://localhost:38472/api/ping
lsof -i :38472Database health
Desktop opens but library/settings look unavailable
The hub may be in degraded mode because the DB is faulted or incompatible.
Check:
curl http://localhost:38472/api/info
curl http://localhost:38472/api/settingsLook for databaseHealth.status.
Recover a faulted DB
Use the local rebuild flow instead of deleting the DB by hand.
curl -X POST http://localhost:38472/api/database/rebuildNotes:
- this route is local-only
- the old DB is preserved and archived before replacement
- a full rescan may start automatically afterwards
Database path and logs
Current default locations:
- DB:
~/.music-hub/music.db - Config:
~/.music-hub/config.json - Electron log:
~/.music-hub/electron.log
Playback
Public share page loads but playback fails
Public share pages depend on bootstrap + signed media sessions.
What to check:
- The share bootstrap endpoint returns
200. - Reloading the same link in the same browser tab should reuse the same
shareSessionIdinstead of creating a new one. - The share page is still renewing
shareSessionIdwith/api/share/session/heartbeat. - The media request includes the latest
mediaToken.
If too many interactive share sessions are active at once for the same page, the server can return 429. Preview bots from WhatsApp, Telegram, Discord, etc. should appear in session telemetry but should not consume that interactive limit.
Playback is slow or stutters
What to check:
- Prefer a strong Wi-Fi signal or a closer route to the hub.
- If remote, confirm the client is not repeatedly falling back after direct-stream failures.
- Restart the current playback session if a stale connection mode was cached.
Remote access
Web session bootstrap failed (403) in the browser (full hub, not /share/)
That message comes from the desktop UI calling POST /api/auth/web-session before protected API calls when the page is loaded on a non-localhost hostname (for example your Cloudflare URL).
Checklist:
-
allowRemoteOpenAccessin config — After toggling Public remote URI in Advanced, confirm~/.music-hub/config.jsonhas"allowRemoteOpenAccess": true. If it staysfalse, the setting did not save (wrong hub process, or the request failed). -
License / remote entitlement — If the hub is not
remoteLicensed, the server returns403withcode: license_required_for_remote(notbrowser_access_disabled). Fix license/validation first. -
Same machine behind the tunnel — The browser must hit the same desktop instance that you configured.
-
Proxy headers — The hub classifies traffic using forwarded client IP headers (
cf-connecting-ip,x-forwarded-for, etc.). If your edge strips them, anonymous browser access rules may not apply as expected.
Public /share/... pages use a separate path: they should load shared content without opening the full hub and without requiring Public remote URI (see share bootstrap in the API docs). If only share pages fail, check the share bootstrap response and license, not only web-session.
Cloudflare/Tailscale route exists but app still cannot browse library
Remote networking alone is not enough anymore. The client still needs auth.
What to check:
- Pair/refresh flow succeeded.
- The remote client is sending
Authorization: Bearer .... - You are not trying to call a local-only endpoint remotely.
Phone was paired on Wi-Fi, Wi-Fi is now off, and covers/search/playback all die together
That path should now work without a re-pair if the phone was already paired once.
What to check:
- The phone is using the latest saved hub config or link from desktop.
- The paired bearer can still reach
/api/media/session,/api/search, and/api/browse. - The desktop remote scope is only limiting public web access, not the phone's private session.
- The mobile diagnostics log does not show repeated
Protected request failedorRemote media session failed.
Share page assets fail behind a custom proxy
Music Hub expects the share page and its static assets to load same-origin, while API CORS stays narrow.
If you front the app with your own proxy:
- Pass
/share/*and static assets through without rewriting them into API requests. - Do not force unknown origins to throw inside API CORS handling.
Mobile iOS shipping
EAS prompts to run git init even though mobile/ is already a git repo
This often happens when Git refuses the repository with dubious ownership (the folder is owned by a different user UID than the account running the build). EAS then assumes there is no usable git metadata.
What to do:
- Prefer fixing ownership:
sudo chown -R "$(whoami)" /path/to/mobile(adjust path). - Or allow the path explicitly:
git config --global --add safe.directory "/absolute/path/to/mobile". - Re-run
npm run build:finalfrommobile/.
The mobile build scripts also attempt to register safe.directory automatically before invoking EAS when they detect this pattern.
Packaging and startup
macOS app is blocked on first open
Because the app is still in beta distribution:
- Right-click the app and choose Open.
- If macOS blocks it, allow it in Privacy & Security.
Splash screen stays visible too long
Check the Electron log first:
tail -f ~/.music-hub/electron.logIf the backend is healthy but the UI is not loading, also test:
curl http://localhost:38472/api/ping
curl http://localhost:38472/api/settingsBuyer / Recovery Flow
I paid, but I lost the original email
Use the current recovery path exposed from the landing flow instead of expecting a permanent raw DMG URL.
The download link expired
That is expected for the current secure download flow. Use the recovery flow to generate a fresh short-lived download link.