we-promise/sure · error · ActiveRecord::RecordNotFound

record_not_found

record_not_found

Error message

Security not found

What it means

Raised by set_security in Api::V1::SecuritiesController (app/controllers/api/v1/securities_controller.rb:32). The valid_uuid? guard rejects malformed ids with the custom 'Security not found' RecordNotFound; otherwise securities_scope — Security.where(id: scoped_security_ids) from SecurityResourceFiltering, i.e. securities tied to the family's accounts/holdings — must contain the row. Result is 404 record_not_found.

Source

Thrown at app/controllers/api/v1/securities_controller.rb:32

    @pagy, @securities = pagy(
      securities_query,
      page: safe_page_param,
      limit: @per_page
    )

    render :index
  rescue Api::V1::SecurityResourceFiltering::InvalidFilterError => e
    render_validation_error(e.message)
  end

  def show
    render :show
  end

  private

    def set_security
      raise ActiveRecord::RecordNotFound, "Security not found" unless valid_uuid?(params[:id])

      @security = securities_scope.find(params[:id])
    end

    def ensure_read_scope
      authorize_scope!(:read)
    end

    def securities_scope
      Security
        .where(id: scoped_security_ids)
    end

    def apply_filters(query)
      query = query.where("LOWER(securities.ticker) = ?", params[:ticker].to_s.strip.downcase) if params[:ticker].present?
      query = query.where(exchange_operating_mic: params[:exchange_operating_mic].to_s.strip.upcase) if params[:exchange_operating_mic].present?
      if params[:kind].present?
        invalid_filter!("kind must be one of: #{Security::KINDS.join(', ')}") unless Security::KINDS.include?(params[:kind])

View on GitHub (pinned to e69894adb9)

Solutions

  1. List with GET /api/v1/securities and use an id from that response
  2. If the security is missing, create/hold it via the app first so it enters the family scope
  3. Validate UUID format before the call
  4. Handle 404 gracefully — scoped access, not a global catalog
Defensive patterns

Strategy: try-catch

Validate before calling

UUID_RE = /\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/i
UUID_RE.match?(id) or raise ArgumentError, 'security id must be a UUID'

Try / catch

begin
  client.get("/api/v1/securities/#{id}")
rescue Faraday::ResourceNotFound
  # 404 'Security not found': malformed id or security outside family scope
end

Prevention

When it happens

Trigger: GET /api/v1/securities/:id with a non-UUID; a valid UUID for a security the family never held (global security catalog id); a security whose last holding was removed so it dropped out of the scoped set.

Common situations: Harvesting security ids from an external reference/API instead of GET /api/v1/securities; selling all positions and having the security vanish from the family scope; id from a demo seed set.

Related errors


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