diff --git a/lib/aprsme_web/live/packets_live/callsign_view.html.heex b/lib/aprsme_web/live/packets_live/callsign_view.html.heex
index 0b2fb43..c0fa94d 100644
--- a/lib/aprsme_web/live/packets_live/callsign_view.html.heex
+++ b/lib/aprsme_web/live/packets_live/callsign_view.html.heex
@@ -60,7 +60,7 @@
- <% info_field = (packet.data || %{})["information_field"] || "" %>
+ <% info_field = (Map.get(packet, :data) || %{})["information_field"] || "" %>
<%= if String.length(info_field) > 50 do %>
{String.slice(info_field, 0, 50)}...
diff --git a/test/aprsme_web/live/packets_live/callsign_view_test.exs b/test/aprsme_web/live/packets_live/callsign_view_test.exs
new file mode 100644
index 0000000..b3dc4a5
--- /dev/null
+++ b/test/aprsme_web/live/packets_live/callsign_view_test.exs
@@ -0,0 +1,44 @@
+defmodule AprsmeWeb.PacketsLive.CallsignViewTest do
+ use AprsmeWeb.ConnCase
+
+ import Phoenix.LiveViewTest
+
+ describe "live packet broadcast" do
+ test "handles raw broadcast packet without :data key", %{conn: conn} do
+ {:ok, view, _html} = live(conn, "/packets/DB0WUN-13")
+
+ # Simulate a raw broadcast payload (as it arrives from the APRS pipeline)
+ # This map does NOT have a :data key — only %Packet{} structs do
+ raw_payload = %{
+ sender: "DB0WUN-13",
+ data_type: :weather,
+ destination: "APN000",
+ path: "TCPIP*,qAC,T2EISBERG",
+ base_callsign: "DB0WUN",
+ ssid: "13",
+ received_at: DateTime.utc_now(),
+ latitude: Decimal.new("50.0001"),
+ longitude: Decimal.new("12.1393"),
+ temperature: 31,
+ humidity: 89,
+ wind_speed: 3,
+ comment: "232/003g009t031r000p000P000b10215h89L000eMB63",
+ device_identifier: "APN000",
+ data_extended: %{
+ data_type: :weather,
+ comment: "232/003g009t031r000p000P000b10215h89L000eMB63",
+ latitude: Decimal.new("50.0001"),
+ longitude: Decimal.new("12.1393"),
+ symbol_code: "_",
+ symbol_table_id: "/"
+ }
+ }
+
+ AprsmeWeb.Endpoint.broadcast!("aprs_messages", "packet", raw_payload)
+
+ # Should render without crashing
+ html = render(view)
+ assert html =~ "DB0WUN-13"
+ end
+ end
+end
|