Skip to content

mrp: handle NaN elapsed time when calculating position - #2897

Open
seidnerj wants to merge 1 commit into
postlund:masterfrom
seidnerj:fix-mrp-position-nan
Open

mrp: handle NaN elapsed time when calculating position#2897
seidnerj wants to merge 1 commit into
postlund:masterfrom
seidnerj:fix-mrp-position-nan

Conversation

@seidnerj

Copy link
Copy Markdown

Problem

playing() raises ValueError: cannot convert float NaN to integer when a device
reports NaN as elapsed time, which makes the whole call fail:

File "pyatv/protocols/mrp/__init__.py", line 284, in build_playing_instance
    position=position(),
File "pyatv/protocols/mrp/__init__.py", line 226, in position
    return int(elapsed_time)
ValueError: cannot convert float NaN to integer

Seen in the wild via atvscript (as used by node-pyatv/homebridge-appletv-enhanced),
where the raised error terminates the process.

Cause

elapsedTime and elapsedTimeTimestamp are both double in ContentItemMetadata.proto
(lines 150 and 189), and devices do occasionally report NaN for them. position()
annotated elapsed_time as int and relied on ... or 0 as a fallback, but NaN is
truthy, so it goes straight into int() and raises. total_time() right above already
guards its (also double) duration field with math.isnan; position() never got the
same treatment.

Change

  • Return None from position() when elapsedTime or elapsedTimeTimestamp is NaN,
    consistent with what total_time() does for a NaN duration. A NaN timestamp would
    otherwise raise the same ValueError from datetime.fromtimestamp() inside
    _cocoa_to_timestamp().
  • Correct the elapsed_time annotation from int to float, matching the type the
    protobuf definition actually specifies.

Tests

Added test_metadata_position_nan, which fails on master with the traceback above and
passes with this change. Full test suite and chickn linting pass locally.

Devices sometimes report NaN for the elapsedTime and elapsedTimeTimestamp
metadata fields. Both are doubles in the protobuf definition, so int()
raises ValueError ("cannot convert float NaN to integer") and playing()
fails entirely. NaN is truthy, so the existing "or 0" fallback does not
help. Return None instead, which is what total_time already does for a
NaN duration.

Also correct the elapsed_time annotation from int to float, matching the
type the protobuf definition actually specifies.
seidnerj added a commit to seidnerj/homebridge-appletv-enhanced that referenced this pull request Jul 28, 2026
pyatv 0.18.0 raises "ValueError: cannot convert float NaN to integer" from
mrp.position() when a device reports NaN as elapsed time. node-pyatv rethrows
it and the orphaned rejection in startUp kills the child bridge.

Pin pyatv to the fork carrying the fix until it is released upstream
(postlund/pyatv#2897).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant