Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

FAQ and troubleshooting

The caveats integrators actually hit, collected from the code and the reference applications. The performance page carries the tuning guidance; this page carries what to check when something misbehaves.

Web GPU and browser support

The browser surface needs WebGPU; there is no WebGL fallback. The wasm canvas fails its initialize() when no WebGPU adapter supports the canvas or the device request fails, and then reports the error verbatim. Your page should catch it and present the degradation message: name the missing capability (navigator.gpu is the feature test), and link MDN’s compatibility table. Version floor: Chromium-based browsers since 113 (flag-free), Safari since 26, Firefox since 141 (desktop first), and always a secure context (HTTPS or localhost). No user-agent sniffing.

The map stays empty on an Android emulator after rendering starts. Android emulators render through SwiftShader over ANGLE, a software graphics stack; that is an expected emulator fact, not a failure. On the emulator the GPU surface negotiates through the GL backend: set WGPU_BACKEND=gl in your build’s environment as the reference application does. On real hardware the line is redundant and harmless.

API key and provider failures

How do I supply the provider key? Read it at runtime — from your app’s own secure configuration or a settings surface — and pass it to the provider registration call. Never commit it or bake it into an app bundle. The reference applications ship keyless and take the key from their settings view, with opt-in secure-device storage; their UI suites inject one through a launch intent/environment for automated runs.

The SDK throws immediately at registration when the key is refused. registerMapquestProviders answers with the provider’s verbatim detail; surface it, do not catch-and-continue.

Calls throw RateLimitExhausted. The shared token-bucket limiter is exhausted. The bucket refills on its own schedule, so retry after the next refill instead of surfacing an error; cache-then-network behavior around every provider contract keeps repeated identical requests free of quota.

Calls throw ProviderNotConfigured naming a contract. That contract has no registered implementation on the MapSdk object. Registration is per object: re-registration replaces every slot, so a second registerMapquestProviders call is safe, but a second MapSdk() needs its own registration.

Elevation throws ProviderNotConfigured even with the provider set installed. The elevation contract has no provider implementation yet; its calls keep refusing until one lands.

Offline behavior

Tiles render but routes fail offline, or the other way around. The two offline layers are separate. Tile imagery answers from the disk cache you registered (registerMapquestProvidersWithTileCache), within its byte budget and time-to-live. Routing answers from a compiled routing archive, independent of the imagery cache; check that the archive you compiled covers the queried region (see the next item).

A route refusal comes back offline. The offline graph refuses, rather than guessing, in three cases: bytes that fail the archive validation, a coordinate outside every node’s snap tolerance, and a request pair the graph cannot connect. Check the archive covers the areas you query; a small extract is the usual cause.

Maneuver text has no street names offline. The archived graph carries no street-name strings, so the offline maneuver texts name the turn direction and the distance and stay honest about what they do not know. Named maneuver text arrives from the online provider.

Tile cache

A tuned time-to-live does not stick after re-registration. Registration is a reset: a freshly registered cache starts again at the category default, so re-apply the override after registering. The rasterTileCacheTerms readback shows the effective value.

A large requested time-to-live is accepted but the cache still expires entries. The installed provider’s declared terms ceiling (compliance-bound at 30 calendar days for the imagery) clamps what the cache retains. Read the ceiling from rasterTileCacheTerms and display it next to the effective value.

Setting a zero time-to-live throws. A zero value would expire every entry on capture; the refusal names the mistake.

Compliance

Attribution. Keep the attribution line visible in your application: imagery © MapQuest; map data © OpenStreetMap contributors (ODbL). If you redistribute the SDK or ship an application built on it, reproduce the third-party notices with your distribution.