diff --git a/frontend/src/metabase-types/api/actions.ts b/frontend/src/metabase-types/api/actions.ts
index cf69fdf94657925ce3c2a2e878c7832f4196b5f2..193458b91f342b5271fb58920fe54a13e88b953d 100644
--- a/frontend/src/metabase-types/api/actions.ts
+++ b/frontend/src/metabase-types/api/actions.ts
@@ -18,7 +18,7 @@ export interface WritebackActionBase {
   model_id: CardId;
   name: string;
   description: string | null;
-  parameters: WritebackParameter[];
+  parameters?: WritebackParameter[];
   visualization_settings?: ActionFormSettings;
   archived: boolean;
   creator_id: UserId;
diff --git a/frontend/src/metabase-types/api/mocks/actions.ts b/frontend/src/metabase-types/api/mocks/actions.ts
index daba99ef685b3bf29c424b50e6d48bdb928f3f57..5b62571d294ac1fa1b6c6953fbccb2076966725b 100644
--- a/frontend/src/metabase-types/api/mocks/actions.ts
+++ b/frontend/src/metabase-types/api/mocks/actions.ts
@@ -41,7 +41,7 @@ export const createMockQueryAction = ({
     description: null,
     model_id: 1,
     database_id: 1,
-    parameters: [],
+    parameters: undefined,
     creator_id: creator.id,
     creator,
     archived: false,
@@ -66,7 +66,7 @@ export const createMockImplicitQueryAction = ({
   description: "",
   model_id: 1,
   database_id: 1,
-  parameters: [],
+  parameters: undefined,
   visualization_settings: undefined,
   creator_id: creator.id,
   creator,
diff --git a/frontend/src/metabase/actions/components/ActionViz/ActionDashcardSettings.tsx b/frontend/src/metabase/actions/components/ActionViz/ActionDashcardSettings.tsx
index 56056b3ed9baf3c8e5d8b036e00f84c7d6ed8617..30c79093cd5706f1d4c8e407f898e179ac3a4482 100644
--- a/frontend/src/metabase/actions/components/ActionViz/ActionDashcardSettings.tsx
+++ b/frontend/src/metabase/actions/components/ActionViz/ActionDashcardSettings.tsx
@@ -71,8 +71,8 @@ export function ActionDashcardSettings({
   );
 
   const isFormInvalid =
-    !!action &&
-    action.parameters.some(actionParameter => {
+    action != null &&
+    action.parameters?.some(actionParameter => {
       const isHidden = isParameterHidden(action, actionParameter);
       const isRequired = isParameterRequired(action, actionParameter);
       const isParameterMapped =
diff --git a/frontend/src/metabase/actions/components/ActionViz/ActionDashcardSettings.unit.spec.tsx b/frontend/src/metabase/actions/components/ActionViz/ActionDashcardSettings.unit.spec.tsx
index 27b4ff6e4c43893c14054ecbf2c2e6d89523f71c..440c7e1f21fd2755d89693a62dd878a7535721a2 100644
--- a/frontend/src/metabase/actions/components/ActionViz/ActionDashcardSettings.unit.spec.tsx
+++ b/frontend/src/metabase/actions/components/ActionViz/ActionDashcardSettings.unit.spec.tsx
@@ -456,6 +456,16 @@ describe("ActionViz > ActionDashcardSettings", () => {
     ).toBeInTheDocument();
   });
 
+  it("should be valid and not crash when the action does not have parameters (metabase#32665)", async () => {
+    const { closeSpy } = setup({
+      dashcard: createMockActionDashboardCard({
+        action: createMockQueryAction(),
+      }),
+    });
+    await userEvent.click(screen.getByRole("button", { name: "Done" }));
+    expect(closeSpy).toHaveBeenCalled();
+  });
+
   it("shows parameters for an action", async () => {
     setup({
       dashcard: actionDashcardWithAction,
diff --git a/frontend/src/metabase/actions/hooks/use-action-form/use-action-form.ts b/frontend/src/metabase/actions/hooks/use-action-form/use-action-form.ts
index cef659923055556166f88380879a5c517336020f..95f904d3cfc7b218621d40f26f94cc85bc6af80b 100644
--- a/frontend/src/metabase/actions/hooks/use-action-form/use-action-form.ts
+++ b/frontend/src/metabase/actions/hooks/use-action-form/use-action-form.ts
@@ -6,6 +6,7 @@ import type {
   ActionFormInitialValues,
   ParametersForActionExecution,
   WritebackAction,
+  WritebackParameter,
 } from "metabase-types/api";
 
 import {
@@ -22,27 +23,28 @@ type Opts = {
 };
 
 const INITIAL_VALUES = {};
+const DEFAULT_PARAMETERS: WritebackParameter[] = [];
 
 function useActionForm({
-  action,
+  action: { parameters = DEFAULT_PARAMETERS, visualization_settings },
   initialValues = INITIAL_VALUES,
   prefetchesInitialValues,
 }: Opts) {
   const fieldSettings = useMemo(() => {
     return getOrGenerateFieldSettings(
-      action.parameters,
-      action.visualization_settings?.fields,
+      parameters,
+      visualization_settings?.fields,
     );
-  }, [action]);
+  }, [parameters, visualization_settings]);
 
   const form = useMemo(
-    () => getForm(action.parameters, fieldSettings),
-    [action.parameters, fieldSettings],
+    () => getForm(parameters, fieldSettings),
+    [parameters, fieldSettings],
   );
 
   const validationSchema = useMemo(
-    () => getFormValidationSchema(action.parameters, fieldSettings),
-    [action.parameters, fieldSettings],
+    () => getFormValidationSchema(parameters, fieldSettings),
+    [parameters, fieldSettings],
   );
 
   const cleanedInitialValues = useMemo(() => {