Unable to implement s3 uploads using SimpleS3Upload

I am trying to implement the official guide for s3 External Uploads.

Here is what my liveview looks like:

  @impl true
  def mount(_params, _session, socket) do
    {:ok,
      socket
      |> assign(:uploaded_files, [])
      |> allow_upload(:presentation, accept: ~w(.pptx), max_entries: 3, external: &presign_upload/2)}
  end

  @impl true
  def render(assigns) do
    ~H"""
      <form id="upload-form" phx-submit="save" phx-change="validate">
        <.live_file_input upload={@uploads.presentation} />
        <button type="submit">Upload</button>
      </form>

      <section phx-drop-target={@uploads.presentation.ref}>
        <%= for entry <- @uploads.presentation.entries do %>
          <article class="upload-entry">

            <figure>
              <.live_img_preview entry={entry} />
              <figcaption><%= entry.client_name %></figcaption>
            </figure>

            <%!-- entry.progress will update automatically for in-flight entries --%>
            <progress value={entry.progress} max="100"> <%= entry.progress %>% </progress>

            <%!-- a regular click event whose handler will invoke Phoenix.LiveView.cancel_upload/3 --%>
            <button type="button" phx-click="cancel-upload" phx-value-ref={entry.ref} aria-label="cancel">&times;</button>

            <%!-- Phoenix.Component.upload_errors/2 returns a list of error atoms --%>
            <%= for err <- upload_errors(@uploads.presentation, entry) do %>
              <p class="alert alert-danger"><%= error_to_string(err) %></p>
            <% end %>

          </article>
        <% end %>

        <%!-- Phoenix.Component.upload_errors/1 returns a list of error atoms --%>
        <%= for err <- upload_errors(@uploads.presentation) do %>
          <p class="alert alert-danger"><%= error_to_string(err) %></p>
        <% end %>

      </section>
    """
  end

  @impl true
  def handle_event("validate", _params, socket) do
    {:noreply, socket}
  end

  @impl true
  def handle_event("cancel-upload", %{"ref" => ref}, socket) do
    {:noreply, cancel_upload(socket, :presentation, ref)}
  end

  @impl true
  def handle_event("save", _params, socket) do
    socket
    |> consume_uploaded_entries(:presentation, fn %{key: key}, _ ->
      {:ok, %{"key" => key, "bucket" => "bucket"}}
    end)

    {:noreply, socket}
  end

  defp presign_upload(entry, socket) do
    uploads = socket.assigns.uploads
    bucket = "uploads"
    key = "public/#{entry.client_name}"

    config = %{
      access_key_id: System.fetch_env!("AWS_ACCESS_KEY_ID"),
      secret_access_key: System.fetch_env!("AWS_SECRET_ACCESS_KEY")
    }

    {:ok, fields} =
      SimpleS3Upload.sign_form_upload(config, bucket,
        key: key,
        content_type: entry.client_type,
        max_file_size: uploads[entry.upload_config].max_file_size,
        expires_in: :timer.hours(1)
      )

    meta = %{uploader: "S3", key: key, url: "http://#{bucket}.s3.us-east-005.backblazeb2.com", fields: fields}
    {:ok, meta, socket}
  end

  defp error_to_string(:too_large), do: "Too large"
  defp error_to_string(:too_many_files), do: "You have selected too many files"
  defp error_to_string(:not_accepted), do: "You have selected an unacceptable file type"
  defp error_to_string(:external_client_failure), do: "Cannot connect to external client"
end

and this is my uploader in app.js

let Uploaders = {}

Uploaders.S3 = function(entries, onViewError){
  entries.forEach(entry => {
    let formData = new FormData()
    let {url, fields} = entry.meta
    Object.entries(fields).forEach(([key, val]) => formData.append(key, val))
    formData.append("file", entry.file)
    let xhr = new XMLHttpRequest()
    onViewError(() => xhr.abort())
    xhr.onload = () => xhr.status === 204 ? entry.progress(100) : entry.error()
    xhr.onerror = () => entry.error()
    xhr.upload.addEventListener("progress", (event) => {
      if(event.lengthComputable){
        let percent = Math.round((event.loaded / event.total) * 100)
        if(percent < 100){ entry.progress(percent) }
      }
    })

    xhr.open("POST", url, true)
    xhr.send(formData)
  })
}

let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")

let liveSocket = new LiveSocket("/live", Socket, {
  uploaders: Uploaders,
  params: {_csrf_token: csrfToken}
})

On clicking the upload button (phx-submit) I get this kinda error:

[error] GenServer #PID<0.735.0> terminating
** (KeyError) key "phx-F5V25PnPSWKnPADF" not found in: %{"phx-F5V3Ckri4nYq9hUB" => :presentation}
    :erlang.map_get("phx-F5V25PnPSWKnPADF", %{"phx-F5V3Ckri4nYq9hUB" => :presentation})
    (phoenix_live_view 0.18.18) lib/phoenix_live_view/upload.ex:192: Phoenix.LiveView.Upload.get_upload_by_ref!/2
    (phoenix_live_view 0.18.18) lib/phoenix_live_view/channel.ex:1213: anonymous fn/3 in Phoenix.LiveView.Channel.maybe_update_uploads/2
    (stdlib 4.3) maps.erl:411: :maps.fold_1/3
    (phoenix_live_view 0.18.18) lib/phoenix_live_view/channel.ex:218: Phoenix.LiveView.Channel.handle_info/2
    (stdlib 4.3) gen_server.erl:1123: :gen_server.try_dispatch/4
    (stdlib 4.3) gen_server.erl:1200: :gen_server.handle_msg/6
    (stdlib 4.3) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
Last message: %Phoenix.Socket.Message{topic: "lv:phx-F5V25OcQsvehxgmB", event: "event", payload: %{"event" => "validate", "type" => "form", "uploads" => %{"phx-F5V25PnPSWKnPADF" => [%{"last_modified" => 1697213961787, "name" => "Presentation.pptx", "path" => "presentation", "ref" => "0", "relative_path" => "", "size" => 44902, "type" => "application/vnd.openxmlformats-officedocument.presentationml.presentation"}]}, "value" => "_target=presentation"}, ref: "168", join_ref: "167"}
State: %{components: {%{}, %{}, 1}, join_ref: "167", serializer: Phoenix.Socket.V2.JSONSerializer, socket: #Phoenix.LiveView.Socket<id: "phx-F5V25OcQsvehxgmB", endpoint: ActiveSlidesWeb.Endpoint, view: ActiveSlidesWeb.UserAccountLive, parent_pid: nil, root_pid: #PID<0.735.0>, router: ActiveSlidesWeb.Router, assigns: %{__changed__: %{}, current_user: #ActiveSlides.Accounts.User<__meta__: #Ecto.Schema.Metadata<:loaded, "users">, id: 3, email: "apple@gmail.com", name: "Apple Pie", confirmed_at: nil, inserted_at: ~N[2023-10-22 16:02:13], updated_at: ~N[2023-10-22 16:02:13], ...>, flash: %{}, live_action: :index, uploaded_files: [], uploads: %{__phoenix_refs_to_names__: %{"phx-F5V3Ckri4nYq9hUB" => :presentation}, presentation: #Phoenix.LiveView.UploadConfig<name: :presentation, max_entries: 3, max_file_size: 8000000, entries: [], accept: ".pptx", ref: "phx-F5V3Ckri4nYq9hUB", errors: [], auto_upload?: false, progress_event: nil, ...>}}, transport_pid: #PID<0.643.0>, ...>, topic: "lv:phx-F5V25OcQsvehxgmB", upload_names: %{}, upload_pids: %{}}

I have been stuck on this for so long! :face_with_spiral_eyes: any help would be appreciated