Upstream: GPX upload hard-fails when a waypoint description exceeds 5000 chars #15

Open
opened 2026-07-27 12:45:45 +00:00 by jmz · 2 comments
Owner

Found while bulk-importing 1104 komoot GPX — 26 multi-day routes (Westweg, Haute Route, Tatra Traverse, Brienzergrat…) failed to upload.

Bug: PUT /api/v1/trail/upload (and the folder watcher) hard-fails the entire trail with 500 Failed to create record when any waypoint's description exceeds the waypoints collection limit of 5000 characters. komoot POI/highlight descriptions routinely run 5–6.5k chars.

Root cause: trails_create → waypoints_create propagates the PocketBase validation_max_text_constraint (5000) as a fatal error; the whole GPX (track + all waypoints) is rejected, so the route is lost, not just the one over-long POI.

Repro: upload a GPX whose <wpt><desc> is >5000 chars.

Proposed fix (upstream): truncate an over-long waypoint description to the limit (with an ellipsis) — or skip/relax that single waypoint — instead of aborting the entire trail import. A one-line clamp in the GPX→waypoint mapping (gpx_util) would do it.

Workaround used for our archive: pre-truncate <desc> to ≤4800 before import.

**Found while bulk-importing 1104 komoot GPX** — 26 multi-day routes (Westweg, Haute Route, Tatra Traverse, Brienzergrat…) failed to upload. **Bug:** `PUT /api/v1/trail/upload` (and the folder watcher) **hard-fails the entire trail** with `500 Failed to create record` when *any* waypoint's `description` exceeds the waypoints collection limit of **5000 characters**. komoot POI/highlight descriptions routinely run 5–6.5k chars. **Root cause:** `trails_create → waypoints_create` propagates the PocketBase `validation_max_text_constraint` (5000) as a fatal error; the whole GPX (track + all waypoints) is rejected, so the route is lost, not just the one over-long POI. **Repro:** upload a GPX whose `<wpt><desc>` is >5000 chars. **Proposed fix (upstream):** truncate an over-long waypoint description to the limit (with an ellipsis) — or skip/relax that single waypoint — instead of aborting the entire trail import. A one-line clamp in the GPX→waypoint mapping (`gpx_util`) would do it. Workaround used for our archive: pre-truncate `<desc>` to ≤4800 before import.
Author
Owner

Fix up in #37 (branch fix/waypoint-description-clamp, base main).

Approach: clamp the waypoint description to the waypoints collection's own limit (rune-safe, ellipsis) in createWaypoints before app.Save, so one over-long POI no longer aborts the whole trail import — mirroring the existing photoFiles skip-don't-fail behaviour. Reading the limit from the collection field keeps it correct if the schema limit changes.

Test-first: TestCreateWaypointsClampsOverlongDescription reproduced the exact description: Must be no more than 5000 character(s) abort against a real PocketBase test app before the fix; also a TestClampToRuneLimit table test. Full plugins/importer suite + go vet + go build ./... green.

Prepared during holiday-autopilot — not merged. Upstream submission to open-wanderer/wanderer (dev branch) is the remaining step (owner).

Fix up in #37 (branch `fix/waypoint-description-clamp`, base `main`). **Approach:** clamp the waypoint description to the `waypoints` collection's own limit (rune-safe, ellipsis) in `createWaypoints` before `app.Save`, so one over-long POI no longer aborts the whole trail import — mirroring the existing `photoFiles` skip-don't-fail behaviour. Reading the limit from the collection field keeps it correct if the schema limit changes. **Test-first:** `TestCreateWaypointsClampsOverlongDescription` reproduced the exact `description: Must be no more than 5000 character(s)` abort against a real PocketBase test app before the fix; also a `TestClampToRuneLimit` table test. Full `plugins/importer` suite + `go vet` + `go build ./...` green. Prepared during holiday-autopilot — **not merged**. Upstream submission to open-wanderer/wanderer (dev branch) is the remaining step (owner).
Author
Owner

Expanded this fix to the sibling fields while here: the importer also wrote the waypoint name and the trail name/description unclamped, so an over-long value in any of them aborted the whole import identically (confirmed for waypoint name: name: Must be no more than 255 character(s)). #37 now adds a clampTextField helper that clamps each field to its own limit and applies it to all of them — added TestCreateWaypointsClampsOverlongName; full importer suite + vet + build green. Still not merged.

Expanded this fix to the **sibling fields** while here: the importer also wrote the waypoint *name* and the trail *name/description* unclamped, so an over-long value in any of them aborted the whole import identically (confirmed for waypoint name: `name: Must be no more than 255 character(s)`). #37 now adds a `clampTextField` helper that clamps each field to its own limit and applies it to all of them — added `TestCreateWaypointsClampsOverlongName`; full importer suite + vet + build green. Still not merged.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
public/wanderer#15
No description provided.