actualbudget/actual · warning

Geolocation error:

Error message

Geolocation error:

What it means

A console.warn plus re-throw in the PayeesLocationService getCurrentPosition (packages/desktop-client/src/payees/location-service.ts). When the underlying geolocation provider (navigator.geolocation) fails — permission denied, timeout, or unavailable position — the service logs the raw error and propagates it to callers (position/position1/position2 lookups used to tag payee locations).

Source

Thrown at packages/desktop-client/src/payees/location-service.ts:37

    private geolocation: GeolocationAdapter,
    private apiClient: LocationApiClient,
  ) {}

  async getCurrentPosition(): Promise<LocationCoordinates> {
    // Return cached position if it's recent
    if (
      this.currentPosition &&
      Date.now() - this.lastLocationTime < this.CACHE_DURATION
    ) {
      return this.currentPosition;
    }

    try {
      this.currentPosition = await this.geolocation.getCurrentPosition();
      this.lastLocationTime = Date.now();
      return this.currentPosition;
    } catch (error) {
      console.warn('Geolocation error:', error);
      throw error;
    }
  }

  async savePayeeLocation(
    payeeId: string,
    coordinates: LocationCoordinates,
  ): Promise<string> {
    try {
      return await this.apiClient.saveLocation(payeeId, coordinates);
    } catch (error) {
      console.error('Failed to save payee location:', error);
      throw error;
    }
  }

  async getPayeeLocations(payeeId: string): Promise<PayeeLocationEntity[]> {
    try {

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Request geolocation permission (Permissions API) before calling and show an explanatory prompt
  2. Serve the app over HTTPS / configure Electron permission handlers to allow geolocation
  3. Increase the geolocation timeout / enable high-accuracy options in the provider
  4. Catch the rethrown error at call sites and proceed without tagging payee location

Example fix

// before
const pos = await locationService.getCurrentPosition();
// after
let pos;
try {
  pos = await locationService.getCurrentPosition();
} catch {
  pos = null; // proceed without location tagging
}
Defensive patterns

Strategy: try-catch

Validate before calling

const perm = await navigator.permissions?.query({ name: 'geolocation' });
if (perm && perm.state === 'denied') console.warn('Geolocation unavailable: permission denied');

Type guard

function isGeolocationError(e: unknown): e is GeolocationPositionError {
  return typeof e === 'object' && e !== null && 'code' in e && 'PERMISSION_DENIED' in GeolocationPositionError;
}

Try / catch

try {
  const pos = await locationService.getCurrentPosition();
} catch (e) {
  if (isGeolocationError(e) && e.code === e.PERMISSION_DENIED) showPermissionInstructions();
  else proceedWithoutLocation();
}

Prevention

When it happens

Trigger: Calling getCurrentPosition() when the browser Geolocation API returns a PositionError (code 1 permission-denied, 2 position-unavailable, 3 timeout), or when geolocation is not supported/not secure-context.

Common situations: User denied the location permission prompt; app served over plain HTTP (geolocation blocked); GPS/Wi-Fi positioning unavailable indoors; geolocation timeout on slow devices; desktop app window without location permission.

Related errors


AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29). Data as JSON: /api/errors/1b978475930aad08. Report an issue: GitHub.