metabase
metabase copied to clipboard
Cannot remove filter defaults on Subscriptions
Describe the bug Cannot remove filter defaults on Subscriptions, which means you cannot receive subscription with all results. Seems like it might be a combined FE+BE issue.
To Reproduce
- Question > Sample > Products - save and add to dashboard
- On dashboard, add two filters, one Dropdown connected to Product.Category with default "Doohickey", and one Contains connected to Product.Title with default "Awesome".
- Both filters should have a default value. Save dashboard.
- Open Subscription sidebar, add email recipient, try removing "Doohickey" or "Awesome" - not possible, it restores to the dashboard default.

- When clicking "Awesome" text and deleting the text and "Update filter", then the filter is empty, but trying to send the subscription will cause a stacktrace (see below)

Full stacktrace
2022-07-22 18:42:58,392 ERROR middleware.log :: POST /api/pulse/test 500 89.9 ms (45 DB calls)
{:via [{:type java.lang.NullPointerException, :at [clojure.string$replace invokeStatic "string.clj" 101]}],
:trace
[[clojure.string$replace invokeStatic "string.clj" 101]
[clojure.string$replace invoke "string.clj" 75]
[ring.util.codec$url_encode invokeStatic "codec.clj" 66]
[ring.util.codec$url_encode invoke "codec.clj" 60]
[ring.util.codec$url_encode invokeStatic "codec.clj" 64]
[ring.util.codec$url_encode invoke "codec.clj" 60]
[metabase.pulse.parameters$dashboard_url$iter__54622__54626$fn__54627$iter__54645__54649$fn__54650$fn__54651
invoke
"parameters.clj"
40]
[metabase.pulse.parameters$dashboard_url$iter__54622__54626$fn__54627$iter__54645__54649$fn__54650
invoke
"parameters.clj"
37]
[clojure.lang.LazySeq sval "LazySeq.java" 42]
[clojure.lang.LazySeq seq "LazySeq.java" 51]
[clojure.lang.RT seq "RT.java" 535]
[clojure.core$seq__5419 invokeStatic "core.clj" 139]
[clojure.core$seq__5419 invoke "core.clj" 139]
[clojure.core$tree_seq$walk__6403$fn__6404 invoke "core.clj" 4934]
[clojure.lang.LazySeq sval "LazySeq.java" 42]
[clojure.lang.LazySeq seq "LazySeq.java" 51]
[clojure.lang.RT seq "RT.java" 535]
[clojure.core$seq__5419 invokeStatic "core.clj" 139]
[clojure.core$concat$fn__5510 invoke "core.clj" 727]
[clojure.lang.LazySeq sval "LazySeq.java" 42]
[clojure.lang.LazySeq seq "LazySeq.java" 51]
[clojure.lang.RT seq "RT.java" 535]
[clojure.core$seq__5419 invokeStatic "core.clj" 139]
[clojure.core$filter$fn__5911 invoke "core.clj" 2813]
[clojure.lang.LazySeq sval "LazySeq.java" 42]
[clojure.lang.LazySeq seq "LazySeq.java" 51]
[clojure.lang.RT seq "RT.java" 535]
[clojure.core$seq__5419 invokeStatic "core.clj" 139]
[clojure.core$seq__5419 invoke "core.clj" 139]
[metabase.pulse.parameters$dashboard_url invokeStatic "parameters.clj" 41]
[metabase.pulse.parameters$dashboard_url invoke "parameters.clj" 31]
[metabase.email.messages$pulse_context invokeStatic "messages.clj" 284]
[metabase.email.messages$pulse_context invoke "messages.clj" 280]
[metabase.email.messages$render_pulse_email invokeStatic "messages.clj" 469]
[metabase.email.messages$render_pulse_email invoke "messages.clj" 464]
[metabase.pulse$fn__77163 invokeStatic "pulse.clj" 293]
[metabase.pulse$fn__77163 invoke "pulse.clj" 282]
[clojure.lang.MultiFn invoke "MultiFn.java" 239]
[metabase.pulse$results__GT_notifications$iter__77193__77197$fn__77198 invoke "pulse.clj" 345]
[clojure.lang.LazySeq sval "LazySeq.java" 42]
[clojure.lang.LazySeq seq "LazySeq.java" 51]
[clojure.lang.RT seq "RT.java" 535]
[clojure.core$seq__5419 invokeStatic "core.clj" 139]
[clojure.core$seq__5419 invoke "core.clj" 139]
[metabase.pulse$send_notifications_BANG_ invokeStatic "pulse.clj" 387]
[metabase.pulse$send_notifications_BANG_ invoke "pulse.clj" 386]
[metabase.pulse$send_pulse_BANG_ invokeStatic "pulse.clj" 415]
[metabase.pulse$send_pulse_BANG_ doInvoke "pulse.clj" 395]
[clojure.lang.RestFn invoke "RestFn.java" 410]
[metabase.api.pulse$fn__78350 invokeStatic "pulse.clj" 241]
[metabase.api.pulse$fn__78350 invoke "pulse.clj" 227]
[compojure.core$wrap_response$fn__28036 invoke "core.clj" 160]
[compojure.core$wrap_route_middleware$fn__28020 invoke "core.clj" 132]
[compojure.core$wrap_route_info$fn__28025 invoke "core.clj" 139]
[compojure.core$wrap_route_matches$fn__28029 invoke "core.clj" 151]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$wrap_route_matches$fn__28029 invoke "core.clj" 153]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$wrap_route_matches$fn__28029 invoke "core.clj" 153]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$wrap_route_matches$fn__28029 invoke "core.clj" 153]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$wrap_route_matches$fn__28029 invoke "core.clj" 152]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048 invoke "core.clj" 200]
[metabase.server.middleware.auth$enforce_authentication$fn__67495 invoke "auth.clj" 14]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048 invoke "core.clj" 200]
[compojure.core$make_context$handler__28076 invoke "core.clj" 289]
[compojure.core$make_context$fn__28080 invoke "core.clj" 299]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 199]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 199]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048 invoke "core.clj" 200]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 199]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048 invoke "core.clj" 200]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048 invoke "core.clj" 200]
[metabase.api.routes$fn__78858$fn__78859 invoke "routes.clj" 57]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048 invoke "core.clj" 200]
[clojure.lang.AFn applyToHelper "AFn.java" 160]
[clojure.lang.AFn applyTo "AFn.java" 144]
[clojure.core$apply invokeStatic "core.clj" 667]
[clojure.core$apply invoke "core.clj" 662]
[metabase.server.routes$fn__79008$fn__79009 doInvoke "routes.clj" 67]
[clojure.lang.RestFn invoke "RestFn.java" 436]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048 invoke "core.clj" 200]
[compojure.core$make_context$handler__28076 invoke "core.clj" 289]
[compojure.core$make_context$fn__28080 invoke "core.clj" 299]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$wrap_route_matches$fn__28029 invoke "core.clj" 153]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$wrap_route_matches$fn__28029 invoke "core.clj" 153]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$wrap_route_matches$fn__28029 invoke "core.clj" 153]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 199]
[compojure.core$routes$fn__28048$f__28049$respond_SINGLEQUOTE___28050 invoke "core.clj" 197]
[compojure.core$make_context$fn__28080 invoke "core.clj" 300]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048 invoke "core.clj" 200]
[compojure.core$routes$fn__28048$f__28049 invoke "core.clj" 198]
[compojure.core$routes$fn__28048 invoke "core.clj" 200]
[metabase.server.middleware.exceptions$catch_uncaught_exceptions$fn__75820 invoke "exceptions.clj" 98]
[metabase.server.middleware.exceptions$catch_api_exceptions$fn__75817 invoke "exceptions.clj" 86]
[metabase.server.middleware.log$log_api_call$fn__81108$fn__81109$fn__81110 invoke "log.clj" 211]
[metabase.driver.sql_jdbc.execute.diagnostic$do_with_diagnostic_info invokeStatic "diagnostic.clj" 15]
[metabase.driver.sql_jdbc.execute.diagnostic$do_with_diagnostic_info invoke "diagnostic.clj" 9]
[metabase.server.middleware.log$log_api_call$fn__81108$fn__81109 invoke "log.clj" 203]
[toucan.db$_do_with_call_counting invokeStatic "db.clj" 216]
[toucan.db$_do_with_call_counting invoke "db.clj" 209]
[metabase.server.middleware.log$log_api_call$fn__81108 invoke "log.clj" 202]
[metabase.server.middleware.browser_cookie$ensure_browser_id_cookie$fn__86660 invoke "browser_cookie.clj" 38]
[metabase.server.middleware.security$add_security_headers$fn__61088 invoke "security.clj" 148]
[metabase.server.middleware.json$wrap_json_body$fn__83949 invoke "json.clj" 63]
[metabase.server.middleware.json$wrap_streamed_json_response$fn__83967 invoke "json.clj" 99]
[metabase.server.middleware.offset_paging$handle_paging$fn__61112 invoke "offset_paging.clj" 42]
[ring.middleware.keyword_params$wrap_keyword_params$fn__86927 invoke "keyword_params.clj" 55]
[ring.middleware.params$wrap_params$fn__86946 invoke "params.clj" 77]
[metabase.server.middleware.misc$maybe_set_site_url$fn__35185 invoke "misc.clj" 59]
[metabase.server.middleware.session$bind_current_user$fn__46657$fn__46658 invoke "session.clj" 291]
[metabase.server.middleware.session$do_with_current_user invokeStatic "session.clj" 270]
[metabase.server.middleware.session$do_with_current_user invoke "session.clj" 259]
[metabase.server.middleware.session$bind_current_user$fn__46657 invoke "session.clj" 290]
[metabase.server.middleware.session$wrap_current_user_info$fn__46639 invoke "session.clj" 240]
[metabase.server.middleware.session$wrap_session_id$fn__46623 invoke "session.clj" 173]
[metabase.server.middleware.auth$wrap_api_key$fn__67503 invoke "auth.clj" 27]
[ring.middleware.cookies$wrap_cookies$fn__86847 invoke "cookies.clj" 216]
[metabase.server.middleware.misc$add_content_type$fn__35168 invoke "misc.clj" 27]
[metabase.server.middleware.misc$disable_streaming_buffering$fn__35193 invoke "misc.clj" 76]
[ring.middleware.gzip$wrap_gzip$fn__86889 invoke "gzip.clj" 86]
[metabase.server.middleware.misc$bind_request$fn__35196 invoke "misc.clj" 93]
[metabase.server.middleware.ssl$redirect_to_https_middleware$fn__86676 invoke "ssl.clj" 38]
[metabase.server$async_proxy_handler$fn__80880 invoke "server.clj" 73]
[metabase.server.proxy$org.eclipse.jetty.server.handler.AbstractHandler$ff19274a handle nil -1]
[org.eclipse.jetty.server.handler.HandlerWrapper handle "HandlerWrapper.java" 127]
[org.eclipse.jetty.server.Server handle "Server.java" 516]
[org.eclipse.jetty.server.HttpChannel lambda$handle$1 "HttpChannel.java" 400]
[org.eclipse.jetty.server.HttpChannel dispatch "HttpChannel.java" 645]
[org.eclipse.jetty.server.HttpChannel handle "HttpChannel.java" 392]
[org.eclipse.jetty.server.HttpConnection onFillable "HttpConnection.java" 277]
[org.eclipse.jetty.io.AbstractConnection$ReadCallback succeeded "AbstractConnection.java" 311]
[org.eclipse.jetty.io.FillInterest fillable "FillInterest.java" 105]
[org.eclipse.jetty.io.ChannelEndPoint$1 run "ChannelEndPoint.java" 104]
[org.eclipse.jetty.util.thread.strategy.EatWhatYouKill runTask "EatWhatYouKill.java" 338]
[org.eclipse.jetty.util.thread.strategy.EatWhatYouKill doProduce "EatWhatYouKill.java" 315]
[org.eclipse.jetty.util.thread.strategy.EatWhatYouKill tryProduce "EatWhatYouKill.java" 173]
[org.eclipse.jetty.util.thread.strategy.EatWhatYouKill run "EatWhatYouKill.java" 131]
[org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread run "ReservedThreadExecutor.java" 409]
[org.eclipse.jetty.util.thread.QueuedThreadPool runJob "QueuedThreadPool.java" 883]
[org.eclipse.jetty.util.thread.QueuedThreadPool$Runner run "QueuedThreadPool.java" 1034]
[java.lang.Thread run "Thread.java" 829]],
:message nil}
Expected behavior Being able to remove the filter defaults for the subscription.
Information about your Metabase Installation: Tested 1.43.4
Additional context Contains filter related #15462
Hi @flamber .My app in Localhost not enable remove value default of variable. Different your screenshot this option of remove in my ap not exist.
Loom video: https://www.loom.com/share/7d6604efb2524a179af2218229ddac7f
@jjromary If you can fix an issue, then just create a PR. If you cannot reproduce an issue, then just leave it for someone else, so we avoid too many comment notifications. This is an Pro/Enterprise feature, which is why my screenshots are pink: https://www.metabase.com/docs/latest/enterprise-guide/dashboard-subscriptions.html
As far as I can tell the expected behavior should be that you can remove "Doohickey" or "Awesome" and it doesn't automatically revert to the default. As the description outlines:
Open Subscription sidebar, add email recipient, try removing "Doohickey" or "Awesome" - not possible, it restores to the dashboard default.
@cdeweyx There are a few places in the code that explicitly ignore setting those values to "null" if defaults are set. And if you do change things around and send null values to the backend, it will sub in the defaults for you (at least using the test pulse route). I'm guessing this is because if you add new parameters after you create the subscription, defaults will still be applied to them. I just wanted to call attention to the fact that it feels like this was built this way intentionally.
@npfitz I reviewed this issue and I think it is safe to implement the behavior Conor described.
I believe this was intentionally implemented like this because our approach to dashboard filter permissions changed. Before, users with no self-service couldn't see field values. Now, we accept that if the user has access to the dashboard, they should be able to interact with any available filter.
This is already possible at the dashboard level. They have access to the data anyway.