How to pass additional arguments to Next.js Server Actions

I am building a file upload page in NextJs.
I Utilised the useActionState alongside initialState.

The issue

If a validation error happend in the backend after submitting, the data retrurned to the frontend except the files. so the user have to re-select them all.
To avoid this behaviour i saved the files in a state (not anymore in the input itslef), this was the best approach since i can’t re-assign the data to the input field of type file.

However i don’t know how to attach them to the request going to the serverAction.

What did I try

I have tried to do it like this:

  const handleFormSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    const formData = new FormData(e.target as HTMLFormElement);
    files.forEach((file) => formData.append("proof", file));
    formAction(formData);
  };

But i get this error after submitting, even tho everything works as expected:

An async function was passed to useActionState, but it was dispatched outside of an action context. This is likely not what you intended. Either pass the dispatch function to an `action` prop, or dispatch manually inside `startTransition`

I have tried to understand this error, but wasn’t able to.

Goal / Expectation

  1. As mentioned above, i want to keep the files until they are successfully uploaded to the cloud.

  2. On success i want to reset the states and remove the files from the state.

My Component

"use client";
import { useActionState, useCallback, useEffect } from "react";
import submit from "./action";
import { twJoin } from "tailwind-merge";
import Main from "@/components/Main";
import { useLocale, useTranslations } from "next-intl";
import Dropzone from "./Dropzone";
import PageHeader from "@/components/PageHeader";
import HugeRoundedButton from "@/components/RoundedButton";
import { useState } from "react";
import { FileRejection } from "react-dropzone";

const initialState = {
  zodErrors: null,
  message: null,
  success: false,
  data: {
    summary: "",
    proof: [],
    note: "",
  },
};
interface PreviewFile extends File {
  preview: string;
}
const CostTracker = () => {
  // States
  const [formState, formAction, pending] = useActionState(submit, initialState);
  const [files, setFiles] = useState<PreviewFile[]>([]);
  const [rejectedFiles, setRejectedFiles] = useState<FileRejection[]>([]);

  const onDrop = useCallback(
    (acceptedFiles: File[], rejectedFiles: FileRejection[]) => {
      if (acceptedFiles.length > 0) {
        setFiles((previousFiles) => [
          ...previousFiles,
          ...acceptedFiles.map((file) =>
            Object.assign(file, {
              preview: URL.createObjectURL(file),
            })
          ),
        ]);
      }

      if (rejectedFiles.length > 0) {
        setRejectedFiles((previousFiles) => [
          ...previousFiles,
          ...rejectedFiles,
        ]);
      }
    },
    []
  );

  const removeFile = (name: string) => {
    // Revoke the data uris to avoid memory leaks
    URL.revokeObjectURL(
      files.find((file) => file.name === name)?.preview as string
    );
    setFiles((files) => files.filter((file) => file.name !== name));
  };
  const removeRejectedFile = (name: string) => {
    setRejectedFiles((rejectedFiles) =>
      rejectedFiles.filter(({ file }) => file.name !== name)
    );
  };

  // Runs when the component unmounts
  useEffect(() => {
    // Make sure to revoke the data uris to avoid memory leaks, will run on unmount
    return () => files.forEach((file) => URL.revokeObjectURL(file.preview));
  }, [files]);

  // Locale
  const locale = useLocale();
  const translations = useTranslations("cost_tracking_page");
  const dir = locale === "ar" ? "rtl" : "ltr";

  // Form State
  const { data, zodErrors, message, success } = formState;

  // Handle form submission
  const handleFormSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    const formData = new FormData(e.target as HTMLFormElement);
    files.forEach((file) => formData.append("proof", file));
    formAction(formData);
  };

  return (
    <Main dir={dir} className="flex-grow gap-6">
      <PageHeader
        title={translations("title")}
        subTitle={translations("subTitle")}
      />
      <form
        onSubmit={handleFormSubmit}
        // action={formAction}
        className="flex flex-col gap-8 bg-primary rounded-3xl px-4 py-8"
        dir={dir}
      >
        <div className="flex gap-2 flex-col">
          <input
            step=".01"
            name="summary"
            type="number"
            defaultValue={data?.summary}
            placeholder={translations("summary_placeholder")}
            className="outline-none p-3 border border-secondary bg-background text-foreground w-full rounded-xl"
          />
          {zodErrors?.summary && (
            <p aria-live="polite" className="text-red-500">
              {zodErrors.summary}
            </p>
          )}
        </div>
        <div className="flex gap-2 flex-col">
          <Dropzone
            files={files}
            onDrop={onDrop}
            onRemoveFile={removeFile}
            rejectedFiles={rejectedFiles}
            onRemoveRejectedFile={removeRejectedFile}
          />
        </div>
        <div className="flex gap-2 flex-col">
          <textarea
            name="note"
            defaultValue={data?.note}
            placeholder={translations("note_placeholder")}
            className="outline-none p-3 border border-secondary bg-background text-foreground w-full rounded-xl min-h-24"
          />
          {zodErrors?.note && (
            <p aria-live="polite" className="text-red-500">
              {zodErrors.note}
            </p>
          )}
        </div>
        <p
          aria-live="assertive"
          className={twJoin(success ? "text-green-500" : "text-red-500")}
        >
          {message}
        </p>
        <HugeRoundedButton
          disabled={pending}
          text={
            pending ? translations("loading") : translations("submit_btn_text")
          }
          className="bg-blue-500 text-white"
        />
      </form>
    </Main>
  );
};

export default CostTracker;

Any Idea on how to achive this?
Thank all.