Skip to content

Bug: PingResponse.from_dict crashes with ValueError when CLI returns ISO-8601 timestamp (macOS arm64 wheel, SDK 0.3.0 + CLI 1.0.51) #1383

@awilliams88

Description

@awilliams88

Summary

PingResponse.from_dict raises a ValueError on macOS (arm64) when the bundled Copilot CLI binary (1.0.51) returns an ISO-8601 string for the timestamp field in the ping JSON-RPC response, because the SDK unconditionally parses it with int(timestamp).


Environment

Property Value
SDK version github-copilot-sdk 0.3.0
Platform macOS arm64 (Apple Silicon)
Python version 3.13
Bundled CLI version 1.0.51 (from copilot/bin/copilot --version)
copilot/bin/VERSION file 1.0.36-0

Steps to Reproduce

  1. Install the SDK on macOS arm64:
    pip install github-copilot-sdk==0.3.0
  2. Start the bundled CLI server and connect a CopilotClient using ExternalServerConfig — it will call client.start() which internally calls ping().

Error

ValueError: invalid literal for int() with base 10: '2026-05-22T17:50:31.689Z'

Points to copilot/client.py line 204:

return PingResponse(str(message), int(timestamp), int(protocolVersion))

Root Cause

The macOS arm64 wheel of github-copilot-sdk 0.3.0 bundles CLI binary 1.0.51. This binary now returns the ping response's timestamp as an ISO-8601 string instead of a Unix millisecond integer. int(timestamp) raises ValueError on an ISO-8601 string.

The Linux/amd64 wheel is unaffected — it bundles a different binary build that still returns an integer, so no crash occurs there.


Suggested Fix

def _parse_timestamp(value: object) -> int:
    try:
        return int(value)  # type: ignore[arg-type]
    except (ValueError, TypeError):
        from datetime import datetime, timezone
        dt = datetime.fromisoformat(str(value).replace("Z", "+00:00"))
        return int(dt.timestamp() * 1000)

# In PingResponse.from_dict:
return PingResponse(str(message), _parse_timestamp(timestamp), int(protocolVersion))

Note: timestamp is only consumed by _verify_protocol_version which only reads protocolVersion, so a lenient parse here is completely safe.

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions