Skip to content

fix: require at least 2 intermediates for waypoint optimization - #86

Open
akazakou wants to merge 1 commit into
cablate:mainfrom
akazakou:fix/maps_plan_route-crash
Open

fix: require at least 2 intermediates for waypoint optimization#86
akazakou wants to merge 1 commit into
cablate:mainfrom
akazakou:fix/maps_plan_route-crash

Conversation

@akazakou

@akazakou akazakou commented Sep 2, 2026

Copy link
Copy Markdown

Summary

  • Fixes maps_plan_route crashing with Cannot read properties of undefined (reading 'originalName') on every 3-stop route with optimize: true (reported as completely unusable).
  • Root cause: optimizing a single intermediate waypoint is meaningless, so the Routes API returns an unusable optimizedIntermediateWaypointIndex: [-1]. Indexing the geocoded stops with -1 yielded undefined, which then crashed on .originalName.
  • Fixed at the source — optimization is now only requested when it is mathematically meaningful (2+ intermediates / 4+ stops) — plus the constraint is documented in the tool description and covered by unit and smoke tests.

Changes

File Change
src/services/PlacesSearcher.ts planRoute(): shouldOptimize now requires stops.length > 3 (was > 2), so optimization is only requested with 2+ intermediates.
src/services/RoutesService.ts computeRoutes(): guard changed to params.intermediates.length > 1 (was > 0) before setting optimizeWaypointOrder — enforces the constraint at the API-client layer too.
src/tools/maps/planRoute.ts DESCRIPTION now reads "2 to 25 intermediate stops" and states optimization needs 4+ stops (2 intermediates), with 2–3 stops keeping the original order; optimize param .describe() updated to match.
tests/planRoute.unit.test.ts New — 5 network-free unit tests (stubbed geocode + computeRoutes) covering 2 stops (optimize true/false), 3 stops (optimize true/false), and 4 stops with a valid optimized order.
tests/smoke.test.ts New Test 9 — live maps_plan_route invocation: 3-stop regression case (succeeds, no originalName, optimized: false, original order) and 4-stop case (optimized: true, all stops retained). Registered in main().

Test plan

  • npm run build succeeds
  • npm run lint — 0 errors (177 pre-existing warnings; none new, no any added)
  • npm test211 passed, 0 failed (full live smoke suite; was 198 before, +13 new assertions)
  • Manual verification (if applicable)

Additional checks:

  • npm run format:check — passes (this was failing on the new unit test file and would have broken CI; fixed with Prettier)
  • npm run test:unit — 7/7 pass

Verified the new smoke test actually catches the bug. Temporarily reverting both parts of the fix and re-running produces:

🧪 Test 9: Plan route (waypoint optimization thresholds)
  ✅ plan_route (3 stops) returns content
  ❌ plan_route (3 stops, optimize: true) succeeds — got: Error planning route:
     Cannot read properties of undefined (reading 'originalName')
  ❌ plan_route (3 stops) does not surface an originalName crash
 Results: 205 passed, 2 failed

With the fix in place, live API behavior is correct:

3 stops, optimize:true  → API request: intermediates=1, optimizeWaypointOrder=false
                        → API response: optimizedIndex=undefined  → OK, optimized:false, 15.8 km
5 stops, optimize:true  → API request: intermediates=3, optimizeWaypointOrder=true
                        → API response: optimizedIndex=[1,0,2]    → OK, optimized:true,  22.6 km

Changelog entry

- fix: require at least 2 intermediates for plan_route waypoint optimization (#85)

No manual version/CHANGELOG edit is included — .github/workflows/release.yml auto-runs npm version patch, syncs server.json + package-lock.json, generates the CHANGELOG from commit messages, tags, and publishes on merge to main. Hand-bumping would double-bump to 0.0.57 and duplicate the changelog section (visible drift already exists for 0.0.51/0.0.52).


Notes for reviewers

Behavior change: optimize: true on a 2- or 3-stop route is now silently ignored (returns optimized: false) instead of crashing. The response's optimized flag is the source of truth for whether reordering actually happened.

CI cost: Test 9 adds 2 plan_route calls per run (7 geocodes + 2 route computations). Waypoint optimization bills on the higher Compute Routes Pro SKU — small, but it runs on every PR and every push to main.

The Routes API rejects waypoint optimization requests with a single
intermediate stop, so only enable `optimizeWaypointOrder` when there are
more than 3 stops (2+ intermediates).

Also add unit tests for `planRoute` covering 2, 3 and more stops with
optimization enabled and disabled, using stubbed geocoding and Routes
API responses.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant