diff --git a/src/metabase/lib/js.cljs b/src/metabase/lib/js.cljs
index 460db79479fde7d1a35fc03c12ae70a46abbe3db..eb68caed8dab0e39f8329c306bcc5bb80dbedb04 100644
--- a/src/metabase/lib/js.cljs
+++ b/src/metabase/lib/js.cljs
@@ -9,6 +9,7 @@
    [filter])
   (:require
    [clojure.walk :as walk]
+   [goog.object :as gobject]
    [medley.core :as m]
    [metabase.lib.convert :as lib.convert]
    [metabase.lib.core :as lib.core]
@@ -30,10 +31,19 @@
 ;;; this is mostly to ensure all the relevant namespaces with multimethods impls get loaded.
 (comment lib.core/keep-me)
 
+(defn- remove-undefined-properties
+  [obj]
+  (cond-> obj
+    (object? obj) (gobject/filter (fn [e _ _] (not (undefined? e))))))
+
 (defn- convert-js-template-tags [tags]
-  (update-vals (js->clj tags) #(-> %
-                                   (update-keys keyword)
-                                   (update :type keyword))))
+  (-> tags
+      (gobject/map (fn [e _ _]
+                     (remove-undefined-properties e)))
+      js->clj
+      (update-vals #(-> %
+                        (update-keys keyword)
+                        (update :type keyword)))))
 
 (defn ^:export extract-template-tags
   "Extract the template tags from a native query's text.
diff --git a/test/metabase/lib/js_test.cljs b/test/metabase/lib/js_test.cljs
index 3d08f6360f5a3b62be778f45984e4cd429802ce5..8142678297a9768ae42d72b27c4df6832dc2aacf 100644
--- a/test/metabase/lib/js_test.cljs
+++ b/test/metabase/lib/js_test.cljs
@@ -1,6 +1,7 @@
 (ns metabase.lib.js-test
   (:require
    [clojure.test :refer [deftest is testing]]
+   [goog.object :as gobject]
    [metabase.lib.js :as lib.js]
    [metabase.lib.test-metadata :as meta]
    [metabase.lib.test-util :as lib.tu]
@@ -87,24 +88,48 @@
     (is (= ["collection"]
            (js->clj extras)))))
 
+(defn- add-undefined-params
+  "This simulates the FE setting some parameters to js/undefined."
+  [template-tags param-name]
+  (doto (gobject/get template-tags param-name)
+    (gobject/add "options" js/undefined)
+    (gobject/add "default" js/undefined))
+  template-tags)
+
 (deftest ^:parallel template-tags-test
   (testing "Snippets in template tags round trip correctly (#33546)"
     (let [db meta/database
-          snippets {"snippet: my snippet"
+          snippet-name "snippet: my snippet"
+          snippets {snippet-name
                     {:type :snippet
-                     :name "snippet: my snippet",
-                     :id "fd5e96f7-08f8-486b-9919-b2ab72857db4",
-                     :display-name "Snippet: My Snippet",
-                     :snippet-name "my snippet",
+                     :name "snippet: my snippet"
+                     :id "fd5e96f7-08f8-486b-9919-b2ab72857db4"
+                     :display-name "Snippet: My Snippet"
+                     :snippet-name "my snippet"
                      :snippet-id 1}}
           query (lib.js/with-template-tags
                   (lib.js/native-query (:id db) meta/metadata-provider "select * from foo {{snippet: my snippet}}")
-                  (clj->js snippets))]
+                  (add-undefined-params (clj->js snippets) snippet-name))]
       (is (= snippets
              (get-in query [:stages 0 :template-tags])))
       (is (test.js/= (clj->js snippets)
                      (lib.js/template-tags query))))))
 
+(deftest ^:parallel extract-template-tags-test
+  (testing "Undefined parameters are ignored (#34729)"
+    (let [tag-name "foo"
+          tags {tag-name {:type         :text
+                          :name         tag-name
+                          :display-name "Foo"
+                          :id           (str (random-uuid))}}]
+      (is (= {"bar" {"type"         "text"
+                     "name"         "bar"
+                     "display-name" "Bar"
+                     "id"           (get-in tags [tag-name :id])}}
+             (-> (lib.js/extract-template-tags "SELECT * FROM table WHERE {{bar}}"
+                                               (add-undefined-params (clj->js tags) tag-name))
+                 js->clj))))))
+
 (deftest ^:parallel is-column-metadata-test
   (is (true? (lib.js/is-column-metadata (meta/field-metadata :venues :id))))
   (is (false? (lib.js/is-column-metadata 1))))