Skip to content

Directions hides unresolved destinations for live-origin routes and still lets them be re-shared #160

Open

Description

@lnorton89

Problem

Directions only renders its unresolved-endpoint warning when the origin is not live:

{!preview && to && from.kind !== 'live' && (
  <Typography variant="caption" color="warning.main">
    One of these endpoints cannot be resolved against the current map data.
  </Typography>
)}

At the same time, Share link is enabled for any non-empty to, even when the route cannot resolve:

<Button ... disabled={!to} onClick={onShare}>
  Share link
</Button>

and shareDirections() serializes the raw endpoint state without requiring directionsPreview/successful endpoint resolution:

if (!directionsTo) return
shareLink(
  directionsUrl({ version: 1, from: directionsFrom, to: directionsTo, mode: directionsMode }),
  'Dust Compass directions',
)

This creates a silent failure path for the most common route shape, From = Your location.

A current-year Directions URL can contain a syntactically valid but no-longer-existing POI UID, for example from=live&to=poi:<stale-uid>. readDirectionsIntent() accepts that endpoint because it only validates the serialized shape. resolveDirectionsEndpoint() then fails because the UID is absent from context.pois, so preview is undefined.

Because from.kind === 'live', the generic unresolved-endpoint warning is deliberately suppressed. The panel can therefore show a normal Your location follows your live GPS position status while giving no explanation for why no route appears and Start navigation is disabled. The user can still press Share link, which republishes the same unresolved route.

This is distinct from #151: #151 covers wrong-year/unsupported/malformed route URLs being rejected before Directions opens. This bug covers a structurally valid current-year Directions intent whose endpoint identity no longer resolves against the current dataset.

Reproduction

Confirmed from current/deployed master at a75401611de02caa4785f875c806b9c72b096a3e in src/ui/DirectionsPanel.tsx, src/App.tsx, and src/data/directionsRuntime.ts.

  1. Construct/open a current-year Directions URL with a valid schema and mode, but use a POI UID that does not exist in the current dataset:
    • dir=1
    • year=2026
    • from=live
    • to=poi:not-a-current-poi
    • mode=walk
  2. readDirectionsIntent() accepts the route because the poi: payload is syntactically valid.
  3. Directions opens with From = Your location and the stale POI endpoint in To state.
  4. resolveDirectionsEndpoint(to) returns undefined because the UID is absent from pois.
  5. directionsPreview is therefore undefined and Start navigation / Route card are disabled.
  6. The unresolved-endpoint warning does not render because its guard requires from.kind !== 'live'.
  7. With a usable GPS fix, the only status shown can be the normal live-location message, providing no indication that the destination itself is stale/unresolvable.
  8. Share link remains enabled because it checks only !to.
  9. Pressing Share link serializes and republishes the same stale poi: endpoint.

The same presentation problem can occur for any unresolved To endpoint while From is live, including a current-year POI removed by a refreshed dataset.

Impact

  • The primary Directions configuration can fail with no diagnosis.
  • A recipient cannot distinguish GPS trouble from a stale/missing destination when no preview appears.
  • Broken current-year route links can be re-shared indefinitely from the app itself.
  • A POI removed by live data refresh can leave an already-open route in a silent dead state.
  • This weakens the explicit stale-link UX already implemented for legacy listing links and the intended compatibility handling in Invalid or old-year Directions links silently collapse to the bare map #151.

Suggested fix

Track endpoint resolution failures separately from live-location acquisition state.

Prefer resolving From and To independently and exposing which endpoint failed, for example:

  • Destination is no longer in the current map. for a missing poi: target;
  • Start location is unavailable. for a failed origin;
  • This playa address can no longer be resolved. for an address endpoint.

Do not suppress an unresolved destination warning merely because From is live.

Disable Share link when the current intent contains an endpoint that is known to be invalid/unresolvable against current data, or make sharing explicitly confirm that the route is unresolved rather than silently propagating it.

If a POI disappears after a live data refresh, surface the stale-destination state immediately instead of leaving the old endpoint looking valid.

Acceptance criteria

  • from=live&to=poi:<missing> opens Directions with a clear stale/unresolved destination message.
  • A usable live GPS fix does not hide destination resolution failure.
  • A GPS acquisition problem and a stale destination are distinguishable in the UI.
  • Start navigation and Route card remain disabled while the destination is unresolved.
  • Share link does not silently republish a route whose endpoint is already known to be unresolved.
  • Fixed/manual-origin unresolved routes retain equivalent explicit error handling.
  • If a currently selected POI disappears after a promoted data refresh, Directions visibly transitions to the same stale-destination state.
  • Add browser/unit coverage for live-origin + missing POI, fixed-origin + missing POI, live-origin + GPS unavailable but valid destination, and POI removal after data refresh.

Activity

  1. added a commit that references this issue on Aug 27, 2026
  2. lnorton89 commented on Aug 27, 2026

    @lnorton89
    OwnerAuthor

    Reopening: the deployed PR #168 fix only validates directionsTo before sharing. directionsDestinationResolved is computed solely from directionsTo, and both the Share button and shareDirections() gate on that destination-only boolean.

    A fixed/manual origin can still be structurally valid but unresolvable against current data (for example from=poi:<missing-uid>&to=man). In that state directionsPreview is undefined and the UI correctly shows The start location cannot be resolved against the current map data, but Share link remains enabled because the destination resolves. Pressing it serializes and republishes the broken origin.

    This directly violates #160's existing acceptance criteria: Share link does not silently republish a route whose endpoint is already known to be unresolved and Fixed/manual-origin unresolved routes retain equivalent explicit error handling.

    Current affected deployed/master SHA: b7ff67f22a8c9d58ee4d05010396f64651da1062.

    Required completion:

    • resolve/track both From and To independently;
    • disable/reject sharing if either fixed endpoint is known unresolved;
    • keep live-origin handling separate from no usable GPS fix so a valid live endpoint is not treated as stale;
    • add regression coverage for missing fixed origin + valid destination, alongside the existing missing-destination cases.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions