{"record":{"id":"956e6235d54c0c21","repo":"home-assistant/core","slug":"keyboard-not-available","errorCode":null,"errorMessage":"keyboard_not_available","messagePattern":"keyboard_not_available","errorType":"validation","errorClass":"ServiceValidationError","httpStatus":null,"severity":"error","filePath":"homeassistant/components/apple_tv/services.py","lineNumber":58,"sourceCode":"    \"\"\"Get the AppleTVInterface for a service call.\"\"\"\n    entry = service.async_get_config_entry(\n        call.hass, DOMAIN, call.data[ATTR_CONFIG_ENTRY_ID]\n    )\n    atv: AppleTVInterface | None = entry.runtime_data.atv\n    if atv is None:\n        raise HomeAssistantError(\n            translation_domain=DOMAIN,\n            translation_key=\"not_connected\",\n        )\n    return atv\n\n\ndef _check_keyboard_focus(atv: AppleTVInterface) -> None:\n    \"\"\"Check that keyboard is focused on the device.\"\"\"\n    try:\n        focus_state = atv.keyboard.text_focus_state\n    except NotSupportedError as err:\n        raise ServiceValidationError(\n            translation_domain=DOMAIN,\n            translation_key=\"keyboard_not_available\",\n        ) from err\n    if focus_state is not KeyboardFocusState.Focused:\n        raise ServiceValidationError(\n            translation_domain=DOMAIN,\n            translation_key=\"keyboard_not_focused\",\n        )\n\n\nasync def _async_set_keyboard_text(call: ServiceCall) -> None:\n    \"\"\"Set text in the keyboard input field on an Apple TV.\"\"\"\n    atv = _get_atv(call)\n    _check_keyboard_focus(atv)\n    try:\n        await atv.keyboard.text_set(call.data[ATTR_TEXT])\n    except ProtocolError as err:\n        raise HomeAssistantError(","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/home-assistant/core/blob/58a3fdb3ea0538617f0a07efcfba6294de64fd59/homeassistant/components/apple_tv/services.py#L40-L76","documentation":"ServiceValidationError with translation key 'keyboard_not_available' raised when querying pyatv's atv.keyboard.text_focus_state raises NotSupportedError - the connected device does not implement the keyboard/text-input protocol at all. Validation happens before any text is sent, so the service call fails fast with a user-facing validation message.","triggerScenarios":"Calling any apple_tv keyboard service (set/append/clear text) on a device where pyatv raises NotSupportedError for keyboard.text_focus_state: tvOS too old for the Remote keyboard protocol, or device exposing no keyboard service over the Companion/MRP channel.","commonSituations":"Older Apple TVs (tvOS < 13ish) or Apple TV clones/airplay-only entries used with keyboard services; feature assumed available because the entity exists but the protocol was never paired; entry connected via AirPlay only without Companion.","solutions":["Verify the entry has the Companion protocol connected (reconfigure so device discovery includes it) and tvOS supports the remote keyboard","Update tvOS on the device; older devices without keyboard support cannot use these services","Use button-sequence automation (send_command) as an alternative on unsupported devices"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"def keyboard_supported(atv) -> bool:\n    try:\n        _ = atv.keyboard.text_focus_state\n        return True\n    except NotSupportedError:\n        return False","tryCatchPattern":"try:\n    focus = atv.keyboard.text_focus_state\nexcept NotSupportedError:\n    skip_keyboard_services()  # device cannot do keyboard input","preventionTips":["Gate keyboard automations on a keyboard_supported check","Ensure Companion protocol is paired, not just AirPlay","Prefer UI-driven typing flows on old tvOS devices"],"tags":["home-assistant","apple-tv","keyboard","not-supported","pyatv"],"backgroundTag":null,"analyzedSha":"58a3fdb3ea0538617f0a07efcfba6294de64fd59","analyzedAt":"2026-08-14T20:54:38.818Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}