The problem
On a Vizio TV whose firmware does not list volume in its audio settings,
media_player.vizio raises KeyError: 'volume' on every coordinator update
(~every 30 s) and the entity stays permanently unavailable. The remote.vizio
entity from the same config entry works normally.
The cause is a single unguarded dictionary lookup in media_player.py. The two
lines immediately after it — for mute and sound mode — are guarded, so this
reads as an oversight rather than a deliberate assumption:
# homeassistant/components/vizio/media_player.py, _handle_coordinator_update
if data.audio_settings:
self._attr_volume_level = (
float(data.audio_settings[VIZIO_VOLUME].value) / self._max_volume # <-- unguarded
)
if VIZIO_MUTE in data.audio_settings: # <-- guarded
...
if VIZIO_SOUND_MODE in data.audio_settings: # <-- guarded
...
Why volume is missing. It has not been removed — this firmware moved it out
of the audio settings collection into its own child resource:
GET /menu_native/dynamic/tv_settings/audio -> 19 items, no "volume"
GET /menu_native/dynamic/tv_settings/audio/volume -> Success, ITEMS[0].CNAME = "volume"
The parent collection returns:
tv_speakers, surround_sound, dialogue_enhancer, volume_leveling, bass, treble,
lip_sync, digital_audio_out, soundbar_settings, soundbar_eq_mode, sounbar_bass,
soundbar_treble, soundbar_dialogue, soundbar_subwoofer, soundbar_night_mode,
soundbar_height, soundbar_virtual_x, soundbar_speaker_test, soundbar_info
while the child resource returns a perfectly good value:
{"CNAME": "volume", "TYPE": "T_VALUE_V1", "NAME": "Volume",
"VALUE": 8, "ENABLED": "FALSE", "HASHVAL": 73865888}
The TV also advertises "AUDIO_2.0_API": true in
/state/device/deviceinfo → CAPABILITIES, which looks like the flag for this
newer audio layout.
The device is fully functional. Against the TV directly, reading volume works,
and volume control works via the ordinary key codes the remote entity already
uses (VOL_UP = codeset 5 / code 1, VOL_DOWN = 5/0). Verified by round-trip:
volume 8 → VOL_UP → 9 → VOL_DOWN → 8. Only Home Assistant's read path is
broken.
What version of Home Assistant Core has the issue?
core-2026.8.0
What was the last working version of Home Assistant Core?
Unknown — believed never to have worked on this firmware.
What type of installation are you running?
Home Assistant Container
Integration causing the issue
Vizio SmartCast
Link to integration documentation on our website
https://www.home-assistant.io/integrations/vizio/
Example YAML snippet
Not applicable — config entry created through the UI.
Anything in the logs?
ERROR (MainThread) [homeassistant.components.vizio.coordinator] Unexpected error updating listener <id> for vizio
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 202, in async_update_listeners
update_callback()
~~~~~~~~~~~~~~~^^
File "/usr/src/homeassistant/homeassistant/components/vizio/media_player.py", line 206, in _handle_coordinator_update
float(data.audio_settings[VIZIO_VOLUME].value) / self._max_volume
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
KeyError: 'volume'
Repeats every ~30 seconds for as long as the TV is powered on.
Additional information
Affected device
|
|
| Model |
V4K50S-0807 (V-Series, 50") |
| Firmware |
86.910.19.1-2 |
| API version |
3.7.2-2621.0005 |
SETTINGS_ROOT |
tv_settings |
| Relevant capability |
AUDIO_2.0_API: true |
Suggested fix — mirrors the guards already present for mute and sound mode:
if VIZIO_VOLUME in data.audio_settings:
self._attr_volume_level = (
float(data.audio_settings[VIZIO_VOLUME].value) / self._max_volume
)
else:
self._attr_volume_level = None
That alone stops the crash and lets the entity load. Actually reporting volume
on these TVs additionally needs the value read from
tv_settings/audio/volume. Note that vizaio already models a
profile-resolved Endpoint.VOLUME_LEVEL (PUT /audio/volume/level), so the
library may already have the plumbing for a per-profile read path.
This is a recurring report that has never been root-caused. The same failure
has been filed at least twice and closed by the stale bot rather than fixed:
There is also direct precedent for exactly this class of fix in this integration:
#32151 switched volume_step to .get() because it is optional, and
#34730 / #34782 added the mute guard after an identical KeyError: 'mute'.
volume appears to be the last unguarded one.
Workaround for anyone finding this issue. Disable the media_player entity
to stop the crash loop (the remote entity is unaffected), then read and control
volume directly:
sensor:
- platform: rest
name: "Vizio Volume"
resource: "https://<tv-ip>:7345/menu_native/dynamic/tv_settings/audio/volume"
headers:
AUTH: !secret vizio_auth_token
verify_ssl: false
value_template: "{{ value_json.ITEMS[0].VALUE }}"
unit_of_measurement: "%"
rest_command:
vizio_volume_up:
url: "https://<tv-ip>:7345/key_command/"
method: PUT
verify_ssl: false
headers:
AUTH: !secret vizio_auth_token
content_type: "application/json"
payload: '{"KEYLIST":[{"CODESET":5,"CODE":1,"ACTION":"KEYPRESS"}]}'
VOL_DOWN is code 0 and MUTE_TOGGLE is code 4 in the same codeset.
The problem
On a Vizio TV whose firmware does not list
volumein its audio settings,media_player.vizioraisesKeyError: 'volume'on every coordinator update(~every 30 s) and the entity stays permanently
unavailable. Theremote.vizioentity from the same config entry works normally.
The cause is a single unguarded dictionary lookup in
media_player.py. The twolines immediately after it — for mute and sound mode — are guarded, so this
reads as an oversight rather than a deliberate assumption:
Why
volumeis missing. It has not been removed — this firmware moved it outof the audio settings collection into its own child resource:
The parent collection returns:
while the child resource returns a perfectly good value:
{"CNAME": "volume", "TYPE": "T_VALUE_V1", "NAME": "Volume", "VALUE": 8, "ENABLED": "FALSE", "HASHVAL": 73865888}The TV also advertises
"AUDIO_2.0_API": truein/state/device/deviceinfo→CAPABILITIES, which looks like the flag for thisnewer audio layout.
The device is fully functional. Against the TV directly, reading volume works,
and volume control works via the ordinary key codes the remote entity already
uses (
VOL_UP= codeset 5 / code 1,VOL_DOWN= 5/0). Verified by round-trip:volume 8 →
VOL_UP→ 9 →VOL_DOWN→ 8. Only Home Assistant's read path isbroken.
What version of Home Assistant Core has the issue?
core-2026.8.0
What was the last working version of Home Assistant Core?
Unknown — believed never to have worked on this firmware.
What type of installation are you running?
Home Assistant Container
Integration causing the issue
Vizio SmartCast
Link to integration documentation on our website
https://www.home-assistant.io/integrations/vizio/
Example YAML snippet
Not applicable — config entry created through the UI.
Anything in the logs?
Repeats every ~30 seconds for as long as the TV is powered on.
Additional information
Affected device
V4K50S-0807(V-Series, 50")86.910.19.1-23.7.2-2621.0005SETTINGS_ROOTtv_settingsAUDIO_2.0_API: trueSuggested fix — mirrors the guards already present for mute and sound mode:
That alone stops the crash and lets the entity load. Actually reporting volume
on these TVs additionally needs the value read from
tv_settings/audio/volume. Note thatvizaioalready models aprofile-resolved
Endpoint.VOLUME_LEVEL(PUT /audio/volume/level), so thelibrary may already have the plumbing for a per-profile read path.
This is a recurring report that has never been root-caused. The same failure
has been filed at least twice and closed by the stale bot rather than fixed:
stale, closed 2025-11-12, with two otherusers confirming ("Same error in logs with 2025.7.3", "Bump on this, same exact
error"). One reporter noted they had spent days re-pairing and reinstalling.
The final comment guesses it was "resolved with update", which appears to be a
misreading — nothing in the integration changed here.
There is also direct precedent for exactly this class of fix in this integration:
#32151 switched
volume_stepto.get()because it is optional, and#34730 / #34782 added the mute guard after an identical
KeyError: 'mute'.volumeappears to be the last unguarded one.Workaround for anyone finding this issue. Disable the
media_playerentityto stop the crash loop (the
remoteentity is unaffected), then read and controlvolume directly:
VOL_DOWNis code0andMUTE_TOGGLEis code4in the same codeset.