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
- Re-list accounts with get_accounts and verify the account_id still exists; retire ids that no longer appear.
- 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.
- Guard callers to treat :not_found per-account: drop the account from the sync set instead of failing the whole job.
- 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
- Reconcile account ids against get_accounts at sync start.
- Keep environment-specific ids separated (staging vs production base_urls).
- Fail per-account, never per-job, on 404s.
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.