we-promise/sure · error · Provider::Lunchflow::LunchflowError

not_found

not_found

Error message

Resource not found

What it means

HTTP 404 branch of Provider::Lunchflow#handle_response (app/models/provider/lunchflow.rb:132-133). Thrown as LunchflowError(:not_found) with message 'Resource not found' when Lunchflow returns 404 for any endpoint: the URL's account id does not exist on the server side (path is /accounts/{url_encoded_id}/...), or the base_url does not match the server's route table (e.g. missing or wrong /api/v1 version prefix so every path 404s).

Source

Thrown at app/models/provider/lunchflow.rb:133

        "x-api-key" => api_key,
        "Content-Type" => "application/json",
        "Accept" => "application/json"
      }
    end

    def handle_response(response)
      case response.code
      when 200
        JSON.parse(response.body, symbolize_names: true)
      when 400
        Rails.logger.error "Lunch Flow API: Bad request - #{response.body}"
        raise LunchflowError.new("Bad request to Lunch Flow API: #{response.body}", :bad_request)
      when 401
        raise LunchflowError.new("Invalid API key", :unauthorized)
      when 403
        raise LunchflowError.new("Access forbidden - check your API key permissions", :access_forbidden)
      when 404
        raise LunchflowError.new("Resource not found", :not_found)
      when 429
        raise LunchflowError.new("Rate limit exceeded. Please try again later.", :rate_limited)
      else
        Rails.logger.error "Lunch Flow API: Unexpected response - Code: #{response.code}, Body: #{response.body}"
        raise LunchflowError.new("Failed to fetch data: #{response.code} #{response.message} - #{response.body}", :fetch_failed)
      end
    end

    class LunchflowError < StandardError
      attr_reader :error_type

      def initialize(message, error_type = :unknown)
        super(message)
        @error_type = error_type
      end
    end
end

View on GitHub (pinned to e69894adb9)

Solutions

  1. Re-list accounts with get_accounts and verify the account_id still exists; retire ids that no longer appear.
  2. If every call 404s (even get_accounts), audit the base_url — it likely has the wrong path/version; it should be https://lunchflow.app/api/v1.
  3. Guard callers to treat :not_found per-account: drop the account from the sync set instead of failing the whole job.
  4. Confirm you are not passing a provider-internal id from another provider.

Example fix

// before
begin
  client.get_account_transactions(acct_id)
rescue => e
  raise # aborts the whole sync on one stale account
end

// after
begin
  client.get_account_transactions(acct_id)
rescue Provider::Lunchflow::LunchflowError => e
  raise unless e.error_type == :not_found
  account.update!(status: 'disconnected') and next_account
end
Defensive patterns

Strategy: fallback

Validate before calling

ids = client.get_accounts[:accounts].map { |a| a[:id] }
acct_ids &= ids # only sync ids that still exist upstream

Type guard

def not_found?(e)
  e.is_a?(Provider::Lunchflow::LunchflowError) && e.error_type == :not_found
end

Try / catch

begin
  client.get_account_balance(acct_id)
rescue Provider::Lunchflow::LunchflowError => e
  raise unless e.error_type == :not_found
  account.mark_deleted_upstream! # skip, keep the rest of the sync running
end

Prevention

When it happens

Trigger: get_account_transactions/balance/holdings called with an account_id deleted at Lunchflow or belonging to a different workspace; ids recorded from a sandbox base_url then used against production; base_url override with a typo'd or missing version segment making all sub-paths unmatched; nil account_id producing '/accounts//transactions'.

Common situations: Accounts unlinked and re-linked upstream while local records keep old ids; environment mismatch between recorded ids and configured base_url; provider deprecating an endpoint (e.g. holdings) with 404 instead of 501.

Related errors


AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21). Data as JSON: /api/errors/69572a17c504f44c. Report an issue: GitHub.