Same-day re-cut on the per-day mutable CalVer scheme (post-v2026.06.04 papercut #2).
False "server offline" → playback "Source error" on a healthy LAN server
On-device: the app reported the server offline while it wasn't, a track failed with load_failed / "Source error", then recovered on its own.
Root cause (proven from the code):
ConnectivityObserver.online gated on NET_CAPABILITY_VALIDATED. That capability tracks whether Android reached its own WAN internet-validation probe (Google's generate_204) — not whether the self-hosted Minstrel server is reachable. The server is usually on the LAN.
A transient WAN/DNS blip (or Android's periodic re-validation) momentarily drops VALIDATED while the LAN server stays reachable. (logcat around the incident shows ERR_NAME_NOT_RESOLVED + Wi-Fi capability churn.)
ServerHealthController flips to Offline the instantonline goes false — no debounce. The /healthz hysteresis added earlier today only guards the ServerDown path.
OfflineGatedDataSource.open() then throws OfflineException on the in-flight stream read → ExoPlayer SOURCE error → PlaybackErrorReporter → the load_failed event.
Fix:
ConnectivityObserver — require INTERNET only, not VALIDATED. The device-link signal now answers only "is there a network at all" (airplane mode); the /healthz poll (VersionCheckController, with its own failure hysteresis) is the authority on whether Minstrel is reachable. A WAN-validation flicker with a healthy LAN no longer reads as offline.
ServerHealthController — add a WARN-tier ServerHealth -> X transition log. The signal had zero instrumentation, which is why this was hard to diagnose from logcat.
Verify on device
Watch adb logcat -s Minstrel during a Wi-Fi/WAN hiccup: ServerHealth should stay Healthy (or go ServerDown only after sustained /healthz failures), never flip to Offline from a brief validation drop. Playback of a streaming (non-cached) track no longer dies with "Source error" on a momentary blip.
Same-day re-cut on the per-day mutable CalVer scheme (post-v2026.06.04 papercut #2).
## False "server offline" → playback "Source error" on a healthy LAN server
On-device: the app reported the server offline while it wasn't, a track failed with `load_failed` / "Source error", then recovered on its own.
**Root cause (proven from the code):**
- `ConnectivityObserver.online` gated on `NET_CAPABILITY_VALIDATED`. That capability tracks whether Android reached its own WAN internet-validation probe (Google's `generate_204`) — **not** whether the self-hosted Minstrel server is reachable. The server is usually on the LAN.
- A transient WAN/DNS blip (or Android's periodic re-validation) momentarily drops `VALIDATED` while the LAN server stays reachable. (logcat around the incident shows `ERR_NAME_NOT_RESOLVED` + Wi-Fi capability churn.)
- `ServerHealthController` flips to `Offline` the **instant** `online` goes false — no debounce. The `/healthz` hysteresis added earlier today only guards the *ServerDown* path.
- `OfflineGatedDataSource.open()` then throws `OfflineException` on the in-flight stream read → ExoPlayer SOURCE error → `PlaybackErrorReporter` → the `load_failed` event.
**Fix:**
- `ConnectivityObserver` — require `INTERNET` only, not `VALIDATED`. The device-link signal now answers only "is there a network at all" (airplane mode); the `/healthz` poll (`VersionCheckController`, with its own failure hysteresis) is the authority on whether Minstrel is reachable. A WAN-validation flicker with a healthy LAN no longer reads as offline.
- `ServerHealthController` — add a WARN-tier `ServerHealth -> X` transition log. The signal had zero instrumentation, which is why this was hard to diagnose from logcat.
## Verify on device
- Watch `adb logcat -s Minstrel` during a Wi-Fi/WAN hiccup: `ServerHealth` should stay `Healthy` (or go `ServerDown` only after sustained `/healthz` failures), never flip to `Offline` from a brief validation drop. Playback of a streaming (non-cached) track no longer dies with "Source error" on a momentary blip.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
A self-hosted Minstrel server is usually on the LAN, but ConnectivityObserver
gated 'online' on NET_CAPABILITY_VALIDATED — which tracks whether Android
reached its own WAN internet-validation probe, not whether Minstrel is
reachable. A transient WAN/DNS blip (or Android's periodic re-validation)
momentarily drops VALIDATED while the LAN server stays reachable. That flipped
ServerHealth -> Offline with NO debounce (only the /healthz path got hysteresis),
and OfflineGatedDataSource fast-failed the in-flight stream read with
OfflineException -> ExoPlayer SOURCE error -> the load_failed 'Source error'
event. On-device: 'app said server offline while it wasn't', one track failed,
then recovered when VALIDATED returned.
- ConnectivityObserver: require INTERNET only, not VALIDATED. The /healthz poll
(VersionCheckController, with its own failure hysteresis) is the authority on
whether Minstrel is reachable; the device-link signal only answers 'is there a
network at all' (airplane mode).
- ServerHealthController: add a WARN-tier transition log. The signal had zero
instrumentation, which is why this was hard to diagnose from logcat.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Same-day re-cut on the per-day mutable CalVer scheme (post-v2026.06.04 papercut #2).
False "server offline" → playback "Source error" on a healthy LAN server
On-device: the app reported the server offline while it wasn't, a track failed with
load_failed/ "Source error", then recovered on its own.Root cause (proven from the code):
ConnectivityObserver.onlinegated onNET_CAPABILITY_VALIDATED. That capability tracks whether Android reached its own WAN internet-validation probe (Google'sgenerate_204) — not whether the self-hosted Minstrel server is reachable. The server is usually on the LAN.VALIDATEDwhile the LAN server stays reachable. (logcat around the incident showsERR_NAME_NOT_RESOLVED+ Wi-Fi capability churn.)ServerHealthControllerflips toOfflinethe instantonlinegoes false — no debounce. The/healthzhysteresis added earlier today only guards the ServerDown path.OfflineGatedDataSource.open()then throwsOfflineExceptionon the in-flight stream read → ExoPlayer SOURCE error →PlaybackErrorReporter→ theload_failedevent.Fix:
ConnectivityObserver— requireINTERNETonly, notVALIDATED. The device-link signal now answers only "is there a network at all" (airplane mode); the/healthzpoll (VersionCheckController, with its own failure hysteresis) is the authority on whether Minstrel is reachable. A WAN-validation flicker with a healthy LAN no longer reads as offline.ServerHealthController— add a WARN-tierServerHealth -> Xtransition log. The signal had zero instrumentation, which is why this was hard to diagnose from logcat.Verify on device
adb logcat -s Minstrelduring a Wi-Fi/WAN hiccup:ServerHealthshould stayHealthy(or goServerDownonly after sustained/healthzfailures), never flip toOfflinefrom a brief validation drop. Playback of a streaming (non-cached) track no longer dies with "Source error" on a momentary blip.🤖 Generated with Claude Code