Error Liveview file upload - (ArgumentError) cannot consume uploaded files when entries are still in progress

I’m trying to upload a csv file, but I’m getting an error.
Has anyone ever experienced this?

** (ArgumentError) cannot consume uploaded files when entries are still in progress
    (phoenix_live_view 0.15.7) lib/phoenix_live_view/upload.ex:238: Phoenix.LiveView.Upload.consume_uploaded_entries/3
    (project 0.1.0) lib/project_web/live/priority_live/index.ex:155: ProjectWeb.PriorityLive.Index.handle_event/3
    (phoenix_live_view 0.15.7) lib/phoenix_live_view/channel.ex:342: anonymous fn/3 in Phoenix.LiveView.Channel.view_handle_event/3
    (telemetry 0.4.3) /project/deps/telemetry/src/telemetry.erl:272: :telemetry.span/3
    (phoenix_live_view 0.15.7) lib/phoenix_live_view/channel.ex:204: Phoenix.LiveView.Channel.handle_info/2
    (stdlib 3.14) gen_server.erl:689: :gen_server.try_dispatch/4
    (stdlib 3.14) gen_server.erl:765: :gen_server.handle_msg/6
    (stdlib 3.14) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
Last message: %Phoenix.Socket.Message{event: "event", join_ref: "4", payload: %{"event" => "submit_csv", "type" => "form", "value" => ""}, ref: "7", topic: "lv:phx-FwDWuGQXK6ER0Svl"}
State: %{components: {%{1 => {ProjectWeb.PriorityLive.ImportMatrix, "import", %{flash: %{}, id: "import", import_table: nil, inner_block: #Function<18.48070371/2 in ProjectWeb.PriorityLive.Index.render/1>, myself: %Phoenix.LiveComponent.CID{cid: 1}, return_to: "/priority_matrix", title: "Importando tabelas", uploaded_files: [], uploads: %{__phoenix_refs_to_names__: %{"phx-FwDWuh5vIgrQhhxI" => :csv_file, "phx-FwDWvQn9RcDQhk1B" => :csv_file}, csv_file: #Phoenix.LiveView.UploadConfig<accept: ".csv,.png", auto_upload?: false, entries: [], errors: [], max_entries: 1, max_file_size: 8000000, name: :csv_file, progress_event: nil, ref: "phx-FwDWvQn9RcDQhk1B", ...>}}, %{changed: %{}, root_view: ProjectWeb.PriorityLive.Index}, {248814122670927342674281395791530970972, %{}}}}, %{ProjectWeb.PriorityLive.ImportMatrix => %{"import" => 1}}, 2}, join_ref: "4", serializer: Phoenix.Socket.V2.JSONSerializer, socket: #Phoenix.LiveView.Socket<assigns: %{all_consult: [...], changeset: #Ecto.Changeset<action: nil, changes: %{}, errors: [], data: #Project.Structure<>, valid?: true>, csv_file: nil, flash: %{}, import_table: "", live_action: :index, matrix: "", ...}, changed: %{}, endpoint: ProjectWeb.Endpoint, id: "phx-FwDWuGQXK6ER0Svl", parent_pid: nil, root_pid: #PID<0.3317.0>, router: ProjectWeb.Router, transport_pid: #PID<0.3314.0>, view: ProjectWeb.PriorityLive.Index, ...>, topic: "lv:phx-FwDWuGQXK6ER0Svl", upload_names: %{}, upload_pids: %{}}

index.html.leex

              <button type="button" class="dropdown-item" phx-click="import_table" phx-target="#import">Importar</button>
              <%= live_component(CcmanagerWeb.PriorityLive.ImportMatrix, id: "import", title: "Importando tabelas") do %>
              <div class="content-wrapper" style="min-height: 10%;">
                <form id="upload-form" phx-submit="submit_csv" phx-change="validate-csv">
                  <%= live_file_input @uploads.csv_file %>
                  <button type="submit" class: "btn btn-primary">Upload</button>
                </form>
                <p class="alert alert-info"><%= live_flash(@flash, :info) %></p>
                <p class="alert alert-danger"><%= live_flash(@flash, :error) %></p>
              </div>
              <% end %>

index.ex

  def mount(params, session, socket) do
    socket = 
      socket
        |> assign(:uploaded_files, [])
        |> allow_upload(:csv_file, accept: ~w(.csv .png), max_entries: 1, auto_upload: true)

    {:ok, assign(socket, all_consult: %{}, import_table: "", csv_file: nil)}
  end

  def handle_event("submit_csv", _params, socket) do
      IO.puts("SUBMIT_CSV")
      uploaded_files = consume_uploaded_entries(socket, :csv_file, fn %{path: path}, _entry ->
        dest = Path.join("priv/static/uploads", Path.basename(path))
        File.cp!(path, dest)
        Routes.static_path(socket, "/uploads/#{Path.basename(dest)}")
      end)
      {:noreply, update(socket, :uploaded_files, &(&1 ++ uploaded_files))}
  end

  def handle_event("validate-csv", _params, socket) do
    {:noreply, socket}
  end

It looks like the entry has not finished uploading when you attempt to consume it. If someone uploads a chunky file and submits the form immediately it may not have uploaded. You can always use something like entry.done? to check that the file has uploaded before calling the consume_uploade_entries/3.

(I know this is resurrecting an old post, I stumbled upon this during an adjacent search).

I am getting the same error. Can you elaborate more about how to resolve it

I assume you have something similar to @gilbertosj where you are getting the uploaded files using teh consume_uploaded_entries/3. If that’s the case it could be that the entry is not finished when you attempt to consume_uploaded_entries/3 because they aren’t finished.

I think it’s best practice working with LiveView uploads to have a handle_progress/3 function which will consume your entries when finished. You assign this function in the original mount/3 something like this:

socket 
|> allow_upload(:images, auto_upload: true, accept: ~w(.jpg .png .jpeg), progress: &handle_progress/3)

...
# then implement handle_progress:

defp handle_progress(:images, entry, socket) do 
  if entry.done? do 
    finished_file = consume_uploaded_entry(socket, entry, fn img -> ... end)

 else 
   {:noreply, socket}
 end 
end

In this case the Phoenix will continually check to see if the image has uploaded, if it hasn’t it will return the socket, but when it finishes the file will be consumed.

Let me know if that’s a bit more clear.