Freika/dawarich · error · Jobs::Create::PaidProviderForceRerunBlocked

Force re-run is not available for paid geocoding providers o

Error message

Force re-run is not available for paid geocoding providers on hosted instances.

What it means

Jobs::Create raises PaidProviderForceRerunBlocked when a user requests the 'start_reverse_geocoding' job (a force re-run over ALL of the user's points) while a paid geocoding provider (Geoapify or LocationIQ) is enabled AND the instance is not marked self-hosted. This is a cost guard: on Dawarich's hosted offering, a forced full re-geocode would re-bill every point through the paid API, so the service refuses up front (after logging a warning with the user id and point count).

Source

Thrown at app/services/jobs/create.rb:83

    ids
  end

  # Cloud users share the operator's geocoding budget, so a click that
  # force-reruns reverse geocoding on a paid provider could fan out to
  # millions of paid lookups. Self-hosted users own their provider key and
  # bill — they keep the override.
  def guard_paid_provider_force_rerun!
    return unless paid_provider?
    return if DawarichSettings.self_hosted?

    point_count = user.points.size
    Rails.logger.warn(
      "[Jobs::Create] Refusing to force-rerun reverse geocoding for user=#{user.id} " \
      "with #{point_count} points: a paid provider (#{paid_provider_name}) is configured " \
      'on a non-self-hosted instance.'
    )

    raise PaidProviderForceRerunBlocked,
          'Force re-run is not available for paid geocoding providers on hosted instances.'
  end

  def paid_provider?
    DawarichSettings.geoapify_enabled? || DawarichSettings.locationiq_enabled?
  end

  def paid_provider_name
    return 'locationiq' if DawarichSettings.locationiq_enabled?
    return 'geoapify' if DawarichSettings.geoapify_enabled?

    'unknown'
  end
end

View on GitHub (pinned to 97fad417c5)

Solutions

  1. Use the 'continue_reverse_geocoding' job instead — it only processes points not yet reverse-geocoded (force: false) and is never blocked by this guard.
  2. If this instance really is self-hosted, enable the self-hosted setting in DawarichSettings so the cost guard is bypassed.
  3. If you call Jobs::Create programmatically, rescue Jobs::Create::PaidProviderForceRerunBlocked and surface a friendly message instead of a 500.

Example fix

# before
Jobs::Create.new('start_reverse_geocoding', current_user.id).call

# after
begin
  Jobs::Create.new('start_reverse_geocoding', current_user.id).call
rescue Jobs::Create::PaidProviderForceRerunBlocked => e
  Rails.logger.info("Blocked: #{e.message}")
  # fall back to only geocoding points that were never geocoded
  Jobs::Create.new('continue_reverse_geocoding', current_user.id).call
end
Defensive patterns

Strategy: try-catch

Validate before calling

blocked =
  job_name == 'start_reverse_geocoding' &&
  (DawarichSettings.geoapify_enabled? || DawarichSettings.locationiq_enabled?) &&
  !DawarichSettings.self_hosted?
return if blocked

Try / catch

begin
  Jobs::Create.new(job_name, user_id).call
rescue Jobs::Create::PaidProviderForceRerunBlocked => e
  # show cost-policy message to user; offer continue_reverse_geocoding instead
rescue Jobs::Create::InvalidJobName => e
  # reject unknown job names
end

Prevention

When it happens

Trigger: Calling Jobs::Create.new('start_reverse_geocoding', user_id).call (e.g. the settings page's "Re-run reverse geocoding" button posting to the jobs endpoint) on an instance where DawarichSettings.self_hosted? is false and DawarichSettings.geoapify_enabled? or locationiq_enabled? is true. The guard runs before any enqueue, so nothing is queued.

Common situations: Hosted Dawarich (app.dawarich.app) users with Geoapify/LocationIQ keys configured clicking force re-run; self-hosters whose SELF_HOSTED setting was never set true after migration, so the instance still looks hosted; CI/staging environments copied from hosted config.

Related errors


AI-assisted analysis of Freika/dawarich@97fad417c5 (2026-08-21). Data as JSON: /api/errors/0e554f55e81d642a. Report an issue: GitHub.