{"record":{"id":"7d731a1c5f88a807","repo":"home-assistant/core","slug":"keyboard-error","errorCode":"keyboard_error","errorMessage":"An error occurred while sending text to the Apple TV","messagePattern":"An error occurred while sending text to the Apple TV","errorType":"exception","errorClass":"HomeAssistantError","httpStatus":null,"severity":"error","filePath":"homeassistant/components/apple_tv/services.py","lineNumber":76,"sourceCode":"        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(\n            translation_domain=DOMAIN,\n            translation_key=\"keyboard_error\",\n        ) from err\n\n\nasync def _async_append_keyboard_text(call: ServiceCall) -> None:\n    \"\"\"Append text to 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_append(call.data[ATTR_TEXT])\n    except ProtocolError as err:\n        raise HomeAssistantError(\n            translation_domain=DOMAIN,\n            translation_key=\"keyboard_error\",\n        ) from err\n\n","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/home-assistant/core/blob/58a3fdb3ea0538617f0a07efcfba6294de64fd59/homeassistant/components/apple_tv/services.py#L58-L94","documentation":"HomeAssistantError with translation key 'keyboard_error' raised when atv.keyboard.text_set(text) fails with a pyatv ProtocolError while the keyboard service tries to set the input field text. The keyboard feature exists and was focused, but the underlying protocol exchange with the device failed.","triggerScenarios":"Calling apple_tv.set_keyboard_text on a focused keyboard field where pyatv raises ProtocolError: device dropped the session mid-write, companion connection reset, or the tvOS keyboard session expired between focus check and text_set.","commonSituations":"Search/password fields on Apple TV that closed while the automation was sending text; network hiccup between HA and the TV; long text payloads timing out the companion channel; device locked mid-operation.","solutions":["Retry after confirming the text field is still open and focused on the device","Reduce payload size / send text in append chunks for long strings","If it repeats, reload the integration to re-establish the Companion session and check network stability"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    await atv.keyboard.text_set(text)\nexcept ProtocolError as ex:\n    _LOGGER.warning(\"keyboard set failed: %s\", ex)\n    await asyncio.sleep(1)\n    # one bounded retry after re-checking focus","preventionTips":["Check focus immediately before sending","Send short payloads; chunk long text","Add a single retry with delay instead of failing the whole automation"],"tags":["home-assistant","apple-tv","keyboard","protocol-error","pyatv"],"backgroundTag":null,"analyzedSha":"58a3fdb3ea0538617f0a07efcfba6294de64fd59","analyzedAt":"2026-08-14T20:54:38.818Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}