we-promise/sure · error · Error
not_found
not_found
Error message
Resource not found
What it means
The API answered HTTP 404 for a well-formed request: the account_number is syntactically valid (sanitize_account_number! passed) but no such resource exists under this credential, or the endpoint itself was removed/moved.
Source
Thrown at app/models/provider/indexa_capital.rb:208
end
def handle_response(response)
case response.code
when 200, 201
begin
JSON.parse(response.body, symbolize_names: true)
rescue JSON::ParserError => e
raise Error.new("Invalid JSON in response: #{e.message}", :bad_response)
end
when 400
Rails.logger.error "IndexaCapital API: Bad request - #{response.body}"
raise Error.new("Bad request: #{response.body}", :bad_request)
when 401
raise AuthenticationError.new("Invalid credentials", :unauthorized)
when 403
raise AuthenticationError.new("Access forbidden - check your permissions", :access_forbidden)
when 404
raise Error.new("Resource not found", :not_found)
when 429
raise Error.new("Rate limit exceeded. Please try again later.", :rate_limited)
when 500..599
raise Error.new("IndexaCapital server error (#{response.code}). Please try again later.", :server_error)
else
Rails.logger.error "IndexaCapital API: Unexpected response - Code: #{response.code}, Body: #{response.body}"
raise Error.new("Unexpected error: #{response.code} - #{response.body}", :unknown)
end
end
# Extract accounts array from /users/me response
# API returns: { accounts: [{ account_number: "ABC12345", type: "mutual", status: "active", ... }] }
def extract_accounts(user_data)
accounts = user_data[:accounts] || []
accounts.map do |acct|
{
account_number: acct[:account_number],
name: account_display_name(acct),View on GitHub (pinned to e69894adb9)
Solutions
- Call list_accounts and diff: accounts missing from the fresh list should be deactivated locally, not retried
- If ALL accounts suddenly 404, suspect an endpoint/contract change - check Indexa API docs before touching data
- Treat :not_found as a permanent condition for that account: stop syncing it rather than retrying
- Verify the exact number character-by-character against the dashboard
Example fix
# before
provider.get_portfolio(account_number: account.account_number)
# after
fresh = provider.list_accounts.map { |a| a[:account_number] }
unless fresh.include?(account.account_number)
account.update!(sync_disabled: true, disable_reason: "gone_from_provider")
next
end
provider.get_portfolio(account_number: account.account_number) Defensive patterns
Strategy: validation
Validate before calling
fresh_numbers = provider.list_accounts.map { |a| a[:account_number] }
unless fresh_numbers.include?(account.account_number)
account.update!(sync_disabled: true, disable_reason: "gone_from_provider")
return
end
provider.get_portfolio(account_number: account.account_number) Type guard
def indexa_not_found?(error) error.is_a?(Provider::IndexaCapital::Error) && error.error_type == :not_found end
Try / catch
begin provider.get_account_balance(account_number: num) rescue Provider::IndexaCapital::Error => e raise unless e.error_type == :not_found account.update!(sync_disabled: true, disable_reason: "not_found_at_provider") # permanent end
Prevention
- Refresh the account list at the start of every sync and diff against stored accounts
- Treat :not_found as permanent for that account - disable, don't retry
- If EVERY account 404s at once, suspect an endpoint change - check docs before bulk-disabling
- Compare stored numbers character-by-character after manual entry
When it happens
Trigger: Account closed at Indexa but still in your sync list; a transposed 8-char code (e.g. "LPYH3CMQ" vs "LPYH3MCQ"); Indexa renamed/removed an endpoint (then every account 404s, not just one); querying fiscal-results for an account type that lacks it entirely.
Common situations: Stale account lists after a user closes an Indexa account, OCR/manual entry of account numbers, API version bumps that moved paths.
Related errors
AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21).
Data as JSON: /api/errors/3b1f4392e0ba5c96.
Report an issue: GitHub.