Phoenix Live Upload fetching nil key when updating progress

So I went through Chris McCord’s liveview upload deep dive Phoenix LiveView Uploads Deep Dive - YouTube and I got it uploading to the local static dir(uploading a single image). I think I’m close in getting it uploaded to S3 but I’m encountering an issue right after presigning(by the way I am not using Amazon S3, but Filebase S3 instead):

[error] GenServer #PID<0.520.0> terminating
** (KeyError) key nil not found in: %{"phx-FpNc9C9o6Eh_cQBG" => :photo}
    :erlang.map_get(nil, %{"phx-FpNc9C9o6Eh_cQBG" => :photo})
    (phoenix_live_view 0.15.7) lib/phoenix_live_view/upload.ex:186: Phoenix.LiveView.Upload.get_upload_by_ref!/2
    (phoenix_live_view 0.15.7) lib/phoenix_live_view/upload.ex:127: Phoenix.LiveView.Upload.update_progress/4

here is presign_entry():

  @bucket "secret-secret"

  defp s3_host, do: "//#{@bucket}.s3.filebase.com"
  defp s3_key(entry), do: "#{entry.uuid}.#{ext(entry)}"


  defp presign_entry(entry, socket) do
    uploads = socket.assigns.uploads
    key = s3_key(entry)

    IO.inspect(key, label: "key s3_key")

    config = %{
      scheme: "https://",
      host: "s3.filebase.com",
      region: "us-east-1",
      access_key_id: "secret", 
      secret_access_key: "secret"
    }

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

    IO.inspect(fields, label: "fields")
    meta = %{uploader: "S3", key: key, url: s3_host(), fields: fields}
    IO.inspect(meta, label: "meta")
    {:ok, meta, socket}

  end

my log shows the presign succeed right before the getting of the nil key:

key s3_key: "b60bd61d-c4a9-41d3-8e56-8550d504c222.jpg"
fields: %{
  "acl" => "public-read",
  "content-type" => "image/jpeg",
  "key" => "b60bd61d-c4a9-41d3-8e56-8550d504c222.jpg",
  "policy" => "ewogICJleHBpcmF0aW9uIjogIjIwMjEtMDctMjBUMDI6NTU6MTEuNzUyMzk5WiIsCiAgImNvbmRpdGlvbnMiOiBbCiAgICB7ImJ1Y2tldCI6ICAid2l0cm9vcy1tYWluIn0sCiAgICBbImVxIiwgIiRrZXkiLCAiYjYwYmQ2MWQtYzRhOS00MWQzLThlNTYtODU1MGQ1MDRjMjIyLmpwZyJdLAogICAgeyJhY2wiOiAicHVibGljLXJlYWQifSwKICAgIFsiZXEiLCAiJENvbnRlbnQtVHlwZSIsICJpbWFnZS9qcGVnIl0sCiAgICBbImNvbnRlbnQtbGVuZ3RoLXJhbmdlIiwgMCwgODAwMDAwMF0sCiAgICB7IngtYW16LXNlcnZlci1zaWRlLWVuY3J5cHRpb24iOiAiQUVTMjU2In0sCiAgICB7IngtYW16LWNyZWRlbnRpYWwiOiAiMUNCQ0M5NUQwQTRCNEU3RDA5QTMvMjAyMTA3MjAvdXMtZWFzdC0xL3MzL2F3czRfcmVxdWVzdCJ9LAogICAgeyJ4LWFtei1hbGdvcml0aG0iOiAiQVdTNC1ITUFDLVNIQTI1NiJ9LAogICAgeyJ4LWFtei1kYXRlIjogIjIwMjEwNzIwVDAyNTUxMVoifQogIF0KfQo=",
  "x-amz-algorithm" => "AWS4-HMAC-SHA256",
  "x-amz-credential" => "1CBCC95D0A4B4E7D09A3/20210720/us-east-1/s3/aws4_request",
  "x-amz-date" => "20210720T025511Z",
  "x-amz-server-side-encryption" => "AES256",
  "x-amz-signature" => "c1a79a82adef92949bef63302c667995c596e6a79b3de3620530991726851762"
}
meta: %{
  fields: %{
    "acl" => "public-read",
    "content-type" => "image/jpeg",
    "key" => "b60bd61d-c4a9-41d3-8e56-8550d504c222.jpg",
    "policy" => "ewogICJleHBpcmF0aW9uIjogIjIwMjEtMDctMjBUMDI6NTU6MTEuNzUyMzk5WiIsCiAgImNvbmRpdGlvbnMiOiBbCiAgICB7ImJ1Y2tldCI6ICAid2l0cm9vcy1tYWluIn0sCiAgICBbImVxIiwgIiRrZXkiLCAiYjYwYmQ2MWQtYzRhOS00MWQzLThlNTYtODU1MGQ1MDRjMjIyLmpwZyJdLAogICAgeyJhY2wiOiAicHVibGljLXJlYWQifSwKICAgIFsiZXEiLCAiJENvbnRlbnQtVHlwZSIsICJpbWFnZS9qcGVnIl0sCiAgICBbImNvbnRlbnQtbGVuZ3RoLXJhbmdlIiwgMCwgODAwMDAwMF0sCiAgICB7IngtYW16LXNlcnZlci1zaWRlLWVuY3J5cHRpb24iOiAiQUVTMjU2In0sCiAgICB7IngtYW16LWNyZWRlbnRpYWwiOiAiMUNCQ0M5NUQwQTRCNEU3RDA5QTMvMjAyMTA3MjAvdXMtZWFzdC0xL3MzL2F3czRfcmVxdWVzdCJ9LAogICAgeyJ4LWFtei1hbGdvcml0aG0iOiAiQVdTNC1ITUFDLVNIQTI1NiJ9LAogICAgeyJ4LWFtei1kYXRlIjogIjIwMjEwNzIwVDAyNTUxMVoifQogIF0KfQo=",
    "x-amz-algorithm" => "AWS4-HMAC-SHA256",
    "x-amz-credential" => "1CBCC95D0A4B4E7D09A3/20210720/us-east-1/s3/aws4_request",
    "x-amz-date" => "20210720T025511Z",
    "x-amz-server-side-encryption" => "AES256",
    "x-amz-signature" => "c1a79a82adef92949bef63302c667995c596e6a79b3de3620530991726851762"
  },
  key: "b60bd61d-c4a9-41d3-8e56-8550d504c222.jpg",
  uploader: "S3",
  url: "//secret-secret.s3.filebase.com"
}

so I’m not sure why this would fail when the upload to the local static dir would succeed? program flow does not even seem to hit defp save_sticker(socket, :new, sticker_params) do I’ve created a gist including log trace of the entire form_component.ex:

Phoenix 1.5.9, liveview 0.15

Any ideas would be greatly appreciated…

Hi, I was having the same error as you.
And I guess I found the solution (at least for me).

The problem was with xhr.onload in uploaders.js

Mine was like this:
xhr.onload = () => xhr.status === 204 || entry.error()

So the function would call on entry.error() everytime, causing the page to break and reloading liveview.
And by reloading liveview, the upload ref id (i.e phx-FpR3OwUkZWgm-g-m) changes, so Phoenix was constantly loosing track of my uploads, giving me that ** (KeyError) key nil not found in: %{"phx-FpR3OwUkZWgm-g-m" => :photo}

So I changed the xhr.onload to:
xhr.onload = () => ((xhr.status === 204 || 200) ? entry.progress(100) : entry.error())
And it stopped giving me the KeyError on Phoenix

hey thanks for the suggestion. So I’m still getting the issue, same error as before. Not sure what it could possibly be, I even attempted with an s3.amazonaws.com bucket, thinking it might be the simple_s3_uploader.ex Thanks anyway though.

Not seeing this issue anymore after upgrading to phoenix 1.6 and liveview 0.16.4.

I too had this issue and updating to 0.16.4 solved it for me. Anyone else having this issue, also check your console in the browser for any pre-sign errors if you’re uploading to s3