diff --git a/frontend/src/metabase-lib/Question.ts b/frontend/src/metabase-lib/Question.ts
index 419fa60dec87020759f8f446703a92790fa0c039..984a89153761ec1abb7e73c13e092d91c808ad8a 100644
--- a/frontend/src/metabase-lib/Question.ts
+++ b/frontend/src/metabase-lib/Question.ts
@@ -459,7 +459,11 @@ class Question {
    * Question is valid (as far as we know) and can be executed
    */
   canRun(): boolean {
-    return this.legacyQuery({ useStructuredQuery: true }).canRun();
+    const { isNative } = Lib.queryDisplayInfo(this.query());
+
+    return isNative
+      ? this.legacyQuery({ useStructuredQuery: true }).canRun()
+      : Lib.canRun(this.query());
   }
 
   canWrite(): boolean {
diff --git a/frontend/src/metabase-lib/queries/StructuredQuery.ts b/frontend/src/metabase-lib/queries/StructuredQuery.ts
index 5b5c9b30ea45f1f41184f4a68fc17ec4c6e854bf..d378d4453e2aa31350737fb085d73217af8ed3d7 100644
--- a/frontend/src/metabase-lib/queries/StructuredQuery.ts
+++ b/frontend/src/metabase-lib/queries/StructuredQuery.ts
@@ -126,13 +126,6 @@ class StructuredQuery extends AtomicQuery {
 
   /* Query superclass methods */
 
-  /**
-   * @returns true if this query is in a state where it can be run.
-   */
-  canRun() {
-    return !!(this._sourceTableId() || this.sourceQuery());
-  }
-
   /**
    * @returns true if we have metadata for the root source table loaded
    */
diff --git a/frontend/src/metabase-lib/query.ts b/frontend/src/metabase-lib/query.ts
index 0c477cf9b4556ef3efb097fbc3c2c9330e09c489..218ba3afc10fafa2a8097d8ca23179d96ee7cf4d 100644
--- a/frontend/src/metabase-lib/query.ts
+++ b/frontend/src/metabase-lib/query.ts
@@ -94,3 +94,7 @@ export function replaceClause(
 export function sourceTableOrCardId(query: Query): TableId | null {
   return ML.source_table_or_card_id(query);
 }
+
+export function canRun(query: Query): boolean {
+  return ML.can_run(query);
+}
diff --git a/frontend/test/metabase-lib/lib/queries/StructuredQuery.unit.spec.js b/frontend/test/metabase-lib/lib/queries/StructuredQuery.unit.spec.js
index 793c6f9a36107fb92393db72c7644508208ebeb1..bbf97f8b28c06ecc21ea2578ee621743b5eb6eb6 100644
--- a/frontend/test/metabase-lib/lib/queries/StructuredQuery.unit.spec.js
+++ b/frontend/test/metabase-lib/lib/queries/StructuredQuery.unit.spec.js
@@ -294,9 +294,6 @@ describe("StructuredQuery", () => {
       it("Expect a reset query to not have a selected database", () => {
         expect(query.reset()._database()).toBe(null);
       });
-      it("Expect a reset query to not be runnable", () => {
-        expect(query.reset().canRun()).toBe(false);
-      });
     });
     describe("query", () => {
       it("returns the wrapper for the query dictionary", () => {
@@ -318,14 +315,6 @@ describe("StructuredQuery", () => {
     });
   });
 
-  describe("QUERY STATUS METHODS", () => {
-    describe("canRun", () => {
-      it("runs a valid query", () => {
-        expect(query.canRun()).toBe(true);
-      });
-    });
-  });
-
   describe("AGGREGATION METHODS", () => {
     describe("aggregations", () => {
       it("should return an empty list for an empty query", () => {
diff --git a/src/metabase/lib/js.cljs b/src/metabase/lib/js.cljs
index ca0a2a1bb53930b3a68f799c5f7082d907ad2994..a8cfb477e88afde30526ee4c75d02bc8ae5aea9c 100644
--- a/src/metabase/lib/js.cljs
+++ b/src/metabase/lib/js.cljs
@@ -1255,3 +1255,8 @@
   for the FE to function properly."
   [a-query]
   (to-array (map clj->js (lib.core/dependent-metadata a-query))))
+
+(defn ^:export can-run
+  "Returns true if the query is runnable."
+  [a-query]
+  (lib.core/can-run a-query))