v0.9.17 — Skip empty-track GPX before EFB upload
Highlights
Stops EFB's silent "konnte nicht interpretiert werden, XML-Fehler!" rejection class — the dominant ongoing error category, affecting 11 distinct users since 2026-04-26.
Root cause
Garmin returns a structurally-valid 658-byte GPX shell with an empty <trkseg/> for activities recorded without GPS (indoors, GPS disabled, manual entry). EFB's parser refuses to interpret a track with zero points and surfaces it as a misleading XML parse error. Diagnosed against prod using v0.9.16's debug-upload?include_gpx=1 — verified the same 658-byte stub across two failing users.
Changes
- New
internal/garmin.HasTrackPoints(gpxData)— cheap byte-level scan for the<trkptmarker. - Sync engine skips empty-track GPX before EFB upload, records the activity as
upload_status = "no_track_points", counts as skipped (not failed), no retries. - Activity-loop status switch handles
"no_track_points"so subsequent sync runs stay idempotent.
Notes
- No schema migration.
synced_activities.upload_statusis unconstrained TEXT. - Backlog cleanup deferred. The 14 existing
permanent_failurerows are inert (already skipped by the activity loop). Optionally reclassify via SQL:UPDATE synced_activities SET upload_status='no_track_points' WHERE upload_status='permanent_failure' AND error_message LIKE '%XML-Fehler%';
PR: #41