{"record":{"id":"8c497c2a61bd4b6f","repo":"home-assistant/core","slug":"local-name-matchers-may-not-have-patterns-in-the-f","errorCode":null,"errorMessage":"Local name matchers may not have patterns in the first {LOCAL_NAME_MIN_MATCH_LENGTH} characters because they would match too broadly ({local_name})","messagePattern":"Local name matchers may not have patterns in the first (.+?) characters because they would match too broadly \\((.+?)\\)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"homeassistant/components/bluetooth/match.py","lineNumber":391,"sourceCode":"        for matcher in self.address.get(service_info.address, []):\n            if ble_device_matches(matcher, service_info):\n                matches.append(matcher)\n        for matcher in self.connectable:\n            if ble_device_matches(matcher, service_info):\n                matches.append(matcher)\n        return matches\n\n\ndef _local_name_to_index_key(local_name: str) -> str:\n    \"\"\"Convert a local name to an index.\n\n    We check the local name matchers here and raise a ValueError\n    if they try to setup a matcher that will is overly broad\n    as would match too many devices and cause a performance hit.\n    \"\"\"\n    match_part = local_name[:LOCAL_NAME_MIN_MATCH_LENGTH]\n    if \"*\" in match_part or \"[\" in match_part:\n        raise ValueError(\n            \"Local name matchers may not have patterns in the first \"\n            f\"{LOCAL_NAME_MIN_MATCH_LENGTH} characters because they \"\n            f\"would match too broadly ({local_name})\"\n        )\n    return match_part\n\n\ndef ble_device_matches(\n    matcher: BluetoothMatcherOptional,\n    service_info: BluetoothServiceInfoBleak,\n) -> bool:\n    \"\"\"Check if a ble device and advertisement_data matches the matcher.\"\"\"\n    # Don't check address here since all callers already\n    # check the address and we don't want to double check\n    # since it would result in an unreachable reject case.\n    if matcher.get(CONNECTABLE, True) and not service_info.connectable:\n        return False\n","sourceCodeStart":373,"sourceCodeEnd":409,"githubUrl":"https://github.com/home-assistant/core/blob/58a3fdb3ea0538617f0a07efcfba6294de64fd59/homeassistant/components/bluetooth/match.py#L373-L409","documentation":"ValueError from _local_name_to_index_key (bluetooth matchers): the first LOCAL_NAME_MIN_MATCH_LENGTH (=3) characters of a local_name matcher contain a glob pattern character ('*' or '['). Such short wildcards would land in the broad index buckets and degrade matching performance for every advertisement, so they are rejected at registration time.","triggerScenarios":"Registering a BluetoothMatcher with local_name='* Sensor' or 'Fo[ox]' — anything where chars 0-2 include * or [ — via the matcher API, integration config (e.g. bluetooth_admin / passive BLE integrations), or an integration's async_register_callback matcher.","commonSituations":"Integration authors writing matchers like local_name: '*flower care*'; users configuring broad name filters hoping to catch many devices; porting matcher YAML from other platforms that allow leading wildcards.","solutions":["Anchor the pattern with at least 3 literal leading characters: 'Flower care*' instead of '*care*'","Prefer matching on service_uuid or manufacturer instead of local_name for broad device families","If you must match a short/prefix-variable name, match on the full literal local_name or use the company_id"],"exampleFix":"# before\nBluetoothMatcher(local_name=\"* sensor\")\n\n# after\nBluetoothMatcher(local_name=\"LYWSD03*\")","handlingStrategy":"validation","validationCode":"from homeassistant.components.bluetooth.match import LOCAL_NAME_MIN_MATCH_LENGTH\n\ndef local_name_matcher_ok(local_name: str) -> bool:\n    return not any(c in local_name[:LOCAL_NAME_MIN_MATCH_LENGTH] for c in (\"*\", \"[\"))","typeGuard":null,"tryCatchPattern":"try:\n    matcher = BluetoothMatcher(local_name=name)\nexcept ValueError as err:\n    if \"patterns in the first\" in str(err):\n        # lengthen the literal prefix or match on service_uuid instead","preventionTips":["Start local_name matchers with at least 3 literal characters","Prefer service_data_uuid / manufacturer/company_id matchers for broad device families"],"tags":["bluetooth","matcher","validation","performance"],"backgroundTag":null,"analyzedSha":"58a3fdb3ea0538617f0a07efcfba6294de64fd59","analyzedAt":"2026-08-14T20:54:38.818Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}