{"record":{"id":"d603500cff8a87fb","repo":"home-assistant/core","slug":"aprs-position-ambiguity-must-be-0-4-not-posambi","errorCode":null,"errorMessage":"APRS position ambiguity must be 0-4, not '{posambiguity}'.","messagePattern":"APRS position ambiguity must be 0-4, not '(.+?)'\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"homeassistant/components/aprs/device_tracker.py","lineNumber":83,"sourceCode":"def make_filter(callsigns: list) -> str:\n    \"\"\"Make a server-side filter from a list of callsigns.\"\"\"\n    return \" \".join(f\"b/{sign.upper()}\" for sign in callsigns)\n\n\ndef gps_accuracy(gps: tuple[float, float], posambiguity: int) -> int:\n    \"\"\"Calculate the GPS accuracy based on APRS posambiguity.\"\"\"\n\n    pos_a_map = {0: 0, 1: 1 / 600, 2: 1 / 60, 3: 1 / 6, 4: 1}\n    if posambiguity in pos_a_map:\n        degrees = pos_a_map[posambiguity]\n\n        gps2 = (gps[0], gps[1] + degrees)\n        dist_m: float = geopy.distance.distance(gps, gps2).m\n\n        accuracy = round(dist_m)\n    else:\n        message = f\"APRS position ambiguity must be 0-4, not '{posambiguity}'.\"\n        raise ValueError(message)\n\n    return accuracy\n\n\ndef setup_scanner(\n    hass: HomeAssistant,\n    config: ConfigType,\n    see: SeeCallback,\n    discovery_info: DiscoveryInfoType | None = None,\n) -> bool:\n    \"\"\"Set up the APRS tracker.\"\"\"\n    callsigns = config[CONF_CALLSIGNS]\n    server_filter = make_filter(callsigns)\n\n    callsign = config[CONF_USERNAME]\n    password = config[CONF_PASSWORD]\n    host = config[CONF_HOST]\n    timeout = config[CONF_TIMEOUT]","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/home-assistant/core/blob/58a3fdb3ea0538617f0a07efcfba6294de64fd59/homeassistant/components/aprs/device_tracker.py#L65-L101","documentation":"Raised as ValueError by gps_accuracy() in the APRS device tracker when a station's posambiguity field is not an integer 0-4. APRS position ambiguity intentionally degrades reported coordinates by dropping digits; the component only implements the five defined ambiguity levels (0 exact up to 1 degree) and rejects anything outside that table.","triggerScenarios":"An APRS packet parsed by aprslib for a tracked callsign carries a posambiguity value not in {0,1,2,3,4} (e.g. None, a string, or >4) when gps_accuracy() is called while processing the position report.","commonSituations":"Malformed or exotic APRS beacon frames from other software/TNCs; packets where aprslib fails to infer ambiguity and yields None; third-party gates injecting non-standard position formats; feeds that include packets not conforming to the APRS spec.","solutions":["Wrap position processing in a try/except ValueError and skip packets with invalid posambiguity instead of letting them fail the tracker loop.","Validate posambiguity with 'if not isinstance(posambiguity, int) or not 0 <= posambiguity <= 4: skip' before calling gps_accuracy.","Report the offending raw packet to aprslib maintainers if aprslib produced the bad value from a spec-compliant frame."],"exampleFix":"# before\naccuracy = gps_accuracy(gps, packet.get('posambiguity'))\n\n# after\npos_amb = packet.get('posambiguity')\nif not isinstance(pos_amb, int) or pos_amb not in range(5):\n    _LOGGER.debug(\"Skipping packet with invalid posambiguity %r\", pos_amb)\n    return\naccuracy = gps_accuracy(gps, pos_amb)","handlingStrategy":"validation","validationCode":"POS_A_VALID = set(range(5))\nif not isinstance(posambiguity, int) or posambiguity not in POS_A_VALID:\n    _LOGGER.debug(\"Dropping packet: bad posambiguity %r\", posambiguity)\n    return None  # skip this packet","typeGuard":"def is_valid_posambiguity(value: object) -> bool:\n    return isinstance(value, int) and not isinstance(value, bool) and 0 <= value <= 4","tryCatchPattern":"try:\n    accuracy = gps_accuracy(gps, packet.get(\"posambiguity\"))\nexcept ValueError:\n    _LOGGER.debug(\"Skipping malformed APRS packet\")\n    return","preventionTips":["Validate posambiguity is an int in 0-4 before computing accuracy.","Treat malformed packets as skippable events, not fatal errors, in tracker loops.","Log raw packets at debug level to diagnose non-conforming beacons."],"tags":["home-assistant","aprs","device-tracker","gps","data-validation"],"backgroundTag":null,"analyzedSha":"58a3fdb3ea0538617f0a07efcfba6294de64fd59","analyzedAt":"2026-08-14T20:54:38.818Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}