home-assistant/core · error · HomeAssistantError

invalid_channel

invalid_channel

Error message

Channel must be numeric: {media_id}

What it means

Raised as HomeAssistantError (translation invalid_channel) when play_media is called with media_type CHANNEL but media_id.isnumeric() is false. The Android TV remote channel feature works by sending each digit as a key press, so a non-numeric channel (e.g. a channel name or URL) cannot be sent. This is pure input validation and no command reaches the device.

Solutions

  1. Pass only digits, e.g. '101' not 'Channel 101' or '101.1'.
  2. For non-numeric targets, launch the channel's app instead (media_type app with a deep link).
  3. Fix the source automation/template that builds media_id.

Example fix

// before
action: androidtv_remote.play_media
data:
  media_content_type: channel
  media_content_id: "HBO HD"
// after
action: androidtv_remote.play_media
data:
  media_content_type: channel
  media_content_id: "501"
Defensive patterns

Strategy: validation

Validate before calling

media_id = '501'
assert media_type != 'channel' or media_id.isnumeric(), 'channel media_id must be digits only'

Type guard

def is_valid_channel(media_id: str) -> bool:
    return media_id.isnumeric()

Try / catch

Not a catch case — a HomeAssistantError shown to the caller; validate media_id before the service call.

Prevention

When it happens

Trigger: A service call like media_player.play_media with media_content_type: channel and media_content_id: 'BBC One' or '5.1' — anything containing non-digit characters fails the isnumeric check.

Common situations: Automations or scripts written for a different integration (e.g. Roku/TV card) reusing channel names; decimals like '5.1'; users pasting call signs instead of numbers.

Related errors


AI-assisted analysis of home-assistant/core@58a3fdb3ea (2026-08-14). Data as JSON: /api/errors/d7369177eff2611a. Report an issue: GitHub.

Appendix: source

Thrown at homeassistant/components/androidtv_remote/media_player.py:191

    @override
    async def async_media_previous_track(self) -> None:
        """Send previous track command."""
        self._send_key_command("MEDIA_PREVIOUS")

    @override
    async def async_media_next_track(self) -> None:
        """Send next track command."""
        self._send_key_command("MEDIA_NEXT")

    @override
    async def async_play_media(
        self, media_type: MediaType | str, media_id: str, **kwargs: Any
    ) -> None:
        """Play a piece of media."""
        if media_type == MediaType.CHANNEL:
            if not media_id.isnumeric():
                raise HomeAssistantError(
                    translation_domain=DOMAIN,
                    translation_key="invalid_channel",
                    translation_placeholders={"media_id": media_id},
                )
            if self._channel_set_task:
                self._channel_set_task.cancel()
            self._channel_set_task = asyncio.create_task(
                self._send_key_commands(list(media_id))
            )
            await self._channel_set_task
            return

        if media_type in [MediaType.URL, MediaType.APP]:
            self._send_launch_app_command(media_id)
            return

        raise HomeAssistantError(
            translation_domain=DOMAIN,

View on GitHub (pinned to 58a3fdb3ea)