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

  1. Call list_accounts and diff: accounts missing from the fresh list should be deactivated locally, not retried
  2. If ALL accounts suddenly 404, suspect an endpoint/contract change - check Indexa API docs before touching data
  3. Treat :not_found as a permanent condition for that account: stop syncing it rather than retrying
  4. 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

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.