home-assistant/core · warning · ValueError

APRS position ambiguity must be 0-4, not '{posambiguity}'.

Error message

APRS position ambiguity must be 0-4, not '{posambiguity}'.

What it means

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.

Source

Thrown at homeassistant/components/aprs/device_tracker.py:83

def make_filter(callsigns: list) -> str:
    """Make a server-side filter from a list of callsigns."""
    return " ".join(f"b/{sign.upper()}" for sign in callsigns)


def gps_accuracy(gps: tuple[float, float], posambiguity: int) -> int:
    """Calculate the GPS accuracy based on APRS posambiguity."""

    pos_a_map = {0: 0, 1: 1 / 600, 2: 1 / 60, 3: 1 / 6, 4: 1}
    if posambiguity in pos_a_map:
        degrees = pos_a_map[posambiguity]

        gps2 = (gps[0], gps[1] + degrees)
        dist_m: float = geopy.distance.distance(gps, gps2).m

        accuracy = round(dist_m)
    else:
        message = f"APRS position ambiguity must be 0-4, not '{posambiguity}'."
        raise ValueError(message)

    return accuracy


def setup_scanner(
    hass: HomeAssistant,
    config: ConfigType,
    see: SeeCallback,
    discovery_info: DiscoveryInfoType | None = None,
) -> bool:
    """Set up the APRS tracker."""
    callsigns = config[CONF_CALLSIGNS]
    server_filter = make_filter(callsigns)

    callsign = config[CONF_USERNAME]
    password = config[CONF_PASSWORD]
    host = config[CONF_HOST]
    timeout = config[CONF_TIMEOUT]

View on GitHub (pinned to 58a3fdb3ea)

Solutions

  1. Wrap position processing in a try/except ValueError and skip packets with invalid posambiguity instead of letting them fail the tracker loop.
  2. Validate posambiguity with 'if not isinstance(posambiguity, int) or not 0 <= posambiguity <= 4: skip' before calling gps_accuracy.
  3. Report the offending raw packet to aprslib maintainers if aprslib produced the bad value from a spec-compliant frame.

Example fix

# before
accuracy = gps_accuracy(gps, packet.get('posambiguity'))

# after
pos_amb = packet.get('posambiguity')
if not isinstance(pos_amb, int) or pos_amb not in range(5):
    _LOGGER.debug("Skipping packet with invalid posambiguity %r", pos_amb)
    return
accuracy = gps_accuracy(gps, pos_amb)
Defensive patterns

Strategy: validation

Validate before calling

POS_A_VALID = set(range(5))
if not isinstance(posambiguity, int) or posambiguity not in POS_A_VALID:
    _LOGGER.debug("Dropping packet: bad posambiguity %r", posambiguity)
    return None  # skip this packet

Type guard

def is_valid_posambiguity(value: object) -> bool:
    return isinstance(value, int) and not isinstance(value, bool) and 0 <= value <= 4

Try / catch

try:
    accuracy = gps_accuracy(gps, packet.get("posambiguity"))
except ValueError:
    _LOGGER.debug("Skipping malformed APRS packet")
    return

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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