# Custom Topic Filters: URL Params Not Reaching \`TopicQuery.options\`

**URL:** https://meta.discourse.org/t/custom-topic-filters-url-params-not-reaching-topicquery-options/367291
**Category:** Development
**Created:** [May 22, 2025, 9:05pm UTC](https://meta.discourse.org/t/custom-topic-filters-url-params-not-reaching-topicquery-options/367291 "2025-05-22T21:05:46Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![SubStrider](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/substrider/32/512604_2.png) [@SubStrider](https://meta.discourse.org/u/SubStrider)
#### Post date: [May 22, 2025, 9:05pm UTC](https://meta.discourse.org/t/custom-topic-filters-url-params-not-reaching-topicquery-options/367291/1 "2025-05-22T21:05:46Z")

</div>

While building a plugin with custom topic list filters (e.g., by price, location) using URL query parameters. The URL updates correctly (e.g., `...?market_item_statuses=Available`), but the parameters aren’t appearing in `topic_query.options` on the server.

**Setup:**

1. **Client-Side Param Registration (`tecenc-discovery-params.js`):**

2. **Server-Side Whitelisting Attempt (`plugin.rb`):**

3. **Server-Side Filtering Logic (`plugin.rb`):**

**The Problem (Logs):**

1. Parameter whitelisting fails:

2. `opts` in `TopicQuery.add_custom_filter` is missing our custom params:  
When URL is `...?market_item_statuses=Available`, log shows:

**Our Environment:**

**Questions:**

1. What’s the current best practice for ensuring custom URL query params reach `topic_query.options` in recent Discourse versions?
2. Why might our attempts to use `add_custom_param_handler` or `extra_options_whitelist` be failing with the “Could not find a suitable method” warning?
3. Is there an alternative approach for parameter registration with `TopicQuery` we should use?

Any help would be much appreciated!

---

<div class="post-metadata">

### Author: ![SubStrider](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/substrider/32/512604_2.png) [@SubStrider](https://meta.discourse.org/u/SubStrider)
#### Post date: [May 23, 2025, 6:41am UTC](https://meta.discourse.org/t/custom-topic-filters-url-params-not-reaching-topicquery-options/367291/2 "2025-05-23T06:41:37Z")

</div>

Just noticed that `add_custom_param_handler` is not even available as a method on TopicQuery. Is there another way to build custom filters for topics in newer discourse versions?

TopicQuery singleton\_methods: [:add\_custom\_filter, :apply\_custom\_filters, :new\_filter, :public\_valid\_options, :remove\_custom\_filter, :remove\_muted\_tags, :results\_filter\_callbacks, :results\_filter\_callbacks=, :tracked\_filter, :unread\_filter, :valid\_options, :validate?, :validators, :yaml\_tag]

---

<div class="post-metadata">

### Author: ![SubStrider](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/substrider/32/512604_2.png) [@SubStrider](https://meta.discourse.org/u/SubStrider)
#### Post date: [May 23, 2025, 11:51am UTC](https://meta.discourse.org/t/custom-topic-filters-url-params-not-reaching-topicquery-options/367291/3 "2025-05-23T11:51:16Z")

</div>

**Progress Report so far:**

1. Confirmed that static `TopicQuery` whitelisting methods like `add_custom_param_handler` or `extra_options_whitelist` are not available as class methods in my Discourse version, so those approaches were abandoned.

2. Implemented a patch for `ListController#build_topic_list_options` to inject my custom URL parameters (e.g., `market_item_statuses`, `market_price_min`) into the `opts` hash before `TopicQuery.new` is called.

3. **This part is now working!** When I make a request like `/c/market/5/l/latest.json?filter=default&market_item_statuses=Available`, my server logs confirm the injection:

**Current Sticking Point: 500 Error & Filter Block Not Reached**

Despite the parameters now being correctly passed to `TopicQuery`’s initializer, I still get a **500 Internal Server Error** when the request includes these custom market parameters.

To isolate this, I simplified my `TopicQuery.add_custom_filter(:"tecenc_market_filters")` block to the absolute minimum.

```ruby
# plugin.rb - Current simplified custom filter block
if ::TopicQuery.respond_to?(:add_custom_filter)
  ::TopicQuery.add_custom_filter(:"tecenc_market_filters") do |topics, topic_query|
    original_topics_relation = topics 
    opts = topic_query.options
    log_prefix_query = "[TecencMarket_SimplifiedFilter_V1.1_Test]" # My debug prefix

    Rails.logger.info "#{log_prefix_query} Opts received by TopicQuery: #{opts.inspect}"

    if opts[:market_item_statuses].present?
      Rails.logger.info "#{log_prefix_query} 'market_item_statuses' IS PRESENT in opts: #{opts[:market_item_statuses]}"
    else
      Rails.logger.info "#{log_prefix_query} 'market_item_statuses' IS NOT PRESENT in opts."
    end
    
    Rails.logger.info "#{log_prefix_query} Returning original topics relation."
    original_topics_relation # Implicit return
  end
  Rails.logger.info "[TecencMarket] Applied SIMPLIFIED custom filter (V1.1_Test)."
end

```

**Observations with this Simplified Filter:**

- **Requests _without_ my custom filter parameter** (e.g., just `/c/market/5/l/latest.json?filter=default`):

- **Requests _with_ my custom filter parameter** (e.g., `/c/market/5/l/latest.json?filter=default&market_item_statuses=Available`):

This indicates the 500 error happens _after_ `TopicQuery` is initialized with the `opts` hash (which now contains my custom parameters), but _before or right as_ Discourse’s core `TopicQuery#apply_custom_filters` mechanism tries to execute my registered (and now extremely simple) filter block.

I am having difficulty isolating the specific Ruby exception and full backtrace from `development.log` that immediately precedes the “Completed 500…” line for the failing requests (the log snippets I’ve gathered show the 500 line itself, but not the detailed error message just before it).

**Follow-up Question:**

Given that:

1. Custom parameters are now being successfully injected into `TopicQuery.options` by the `ListController` patch.

2. A 500 error occurs when these custom parameters are present in `opts`.

3. This 500 error happens _before_ even an extremely simplified custom filter block (that only logs and returns the original relation) gets to execute its first line of code for the request with custom parameters.

4. This is on Discourse `3.5.0.beta3-dev`.

What could be causing `TopicQuery` itself, or its `apply_custom_filters` method, to error out before invoking a registered custom filter block, specifically when the `options` hash contains these plugin-specific keys? Could the previous `LocalJumpError` we suspected still be relevant at a lower level in how `apply_custom_filters` handles the iteration or calling of filter blocks, even if my simplified block is just an implicit return?

Any guidance on what to check next in `TopicQuery`’s behavior with these kinds of custom options, or advice on how to robustly get the full backtrace for the 500 in this scenario, would be immensely helpful.
