Freika/dawarich · warning
Failed to parse track segments:
Error message
Failed to parse track segments:
What it means
When a track is clicked, the handler fetches the full track with segments and expects properties.segments to be either an already-parsed array or a JSON string. If it is a string, JSON.parse() runs inside a try/catch; malformed or truncated JSON throws and logs this warning. segments stays [] so the track still renders, but per-segment colors and hover callbacks show nothing.
Source
Thrown at app/javascript/controllers/maps/maplibre/event_handlers.js:714
/**
* Load track segments from API (lazy loading)
* @private
*/
async _loadTrackSegments(trackId, fullFeature) {
try {
const trackFeature =
await this.controller.api.fetchTrackWithSegments(trackId)
if (!trackFeature) return
let segments = []
try {
const props = trackFeature.properties
segments =
typeof props.segments === "string"
? JSON.parse(props.segments)
: props.segments || []
} catch (err) {
console.warn("Failed to parse track segments:", err)
}
const tracksLayer = this.controller.layerManager.getLayer("tracks")
if (tracksLayer?.showSegments) {
tracksLayer.showSegments(fullFeature, segments)
tracksLayer.setSegmentHoverCallback((segmentIndex) => {
this._highlightSegmentOnMap(segmentIndex)
this._dispatchSegmentHover(trackId, segments[segmentIndex]?.id)
})
tracksLayer.setSegmentLeaveCallback(() => {
this._clearSegmentHighlight()
this._dispatchSegmentUnhover(trackId)
})
}
this._createTrackSegmentMarkers(trackId, fullFeature, segments)
} catch (error) {
console.error("Failed to load track segments:", error)View on GitHub (pinned to 97fad417c5)
Solutions
- Log props.segments (typeof plus first 200 chars) to see whether it is malformed, double-encoded, or an unexpected shape
- Fix the backend serializer to emit valid JSON or a native array — arrays avoid the parse entirely
- Validate the parsed value is an array before using it: Array.isArray(segments) ? segments : []
- Add a serializer regression test covering a track with many segments
Example fix
// before
segments =
typeof props.segments === "string"
? JSON.parse(props.segments)
: props.segments || []
// after
if (typeof props.segments === "string") {
try {
const parsed = JSON.parse(props.segments)
segments = Array.isArray(parsed) ? parsed : []
} catch (err) {
console.warn("Failed to parse track segments:", err)
segments = []
}
} else {
segments = Array.isArray(props.segments) ? props.segments : []
} Defensive patterns
Strategy: try-catch
Validate before calling
function safeParseSegments(raw) {
if (Array.isArray(raw)) return raw
if (typeof raw !== "string" || raw.length === 0) return []
try {
const parsed = JSON.parse(raw)
return Array.isArray(parsed) ? parsed : []
} catch {
return []
}
}
const segments = safeParseSegments(props.segments) Type guard
/** @param {unknown} value @returns {value is Array} */
function isSegmentArray(value) {
return Array.isArray(value)
} Try / catch
try {
segments = safeParseSegments(props.segments)
} catch (err) {
console.warn("Failed to parse track segments:", err)
segments = [] // degrade to no-segment rendering, keep the track visible
} Prevention
- Prefer server-side arrays over JSON strings in GeoJSON properties when payload size allows
- Centralize segment parsing in one shared helper instead of repeating JSON.parse at each call site
- Assert the parsed result is an array, not merely that JSON.parse succeeded
When it happens
Trigger: The tracks serializer emitting invalid JSON in properties.segments (truncated by a response size limit, double-encoded string, NaN serialized by to_json); a backend change wrapping segments in a new shape so the parsed value is not an array; very large segment arrays clipped by a proxy or cache.
Common situations: Long tracks with thousands of points where serialized segments exceed response limits; serializer refactors switching between string and array; caching layers that re-encode JSON; hand-written fixtures with malformed segment strings.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Failed to parse track segments for marker update:
- Failed to add photos layer:
- Failed to apply speed colors to route:
- Could not classify zip contents -- file may be corrupted
- [EventHandlers] Failed to highlight track:
AI-assisted analysis of Freika/dawarich@97fad417c5 (2026-08-21).
Data as JSON: /api/errors/e2b66392cf5efa46.
Report an issue: GitHub.