{"record":{"id":"4716da8c429ab59b","repo":"can1357/oh-my-pi","slug":"ready-supportedprotocolversions-must-be-integers","errorCode":null,"errorMessage":"ready.supportedProtocolVersions must be integers","messagePattern":"ready\\.supportedProtocolVersions must be integers","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/omp-rpc/src/omp_rpc/protocol.py","lineNumber":1633,"sourceCode":"def parse_extension_error(payload: JsonObject) -> ExtensionError:\n    return ExtensionError(\n        extension_path=_require_str(payload, \"extensionPath\"),\n        event=_require_str(payload, \"event\"),\n        error=_require_str(payload, \"error\"),\n    )\n\n\ndef parse_notification(payload: JsonObject) -> RpcNotification:\n    event_type = payload.get(\"type\")\n    if event_type == \"ready\":\n        raw_versions = payload.get(\"supportedProtocolVersions\")\n        supported_versions: tuple[int, ...] | None = None\n        if raw_versions is not None:\n            if not isinstance(raw_versions, list) or any(\n                not isinstance(version, int) or isinstance(version, bool)\n                for version in raw_versions\n            ):\n                raise ValueError(\"ready.supportedProtocolVersions must be integers\")\n            supported_versions = tuple(raw_versions)\n        return ReadyEvent(\n            protocol_version=_optional_int(payload, \"protocolVersion\"),\n            supported_protocol_versions=supported_versions,\n            max_frame_bytes=_optional_int(payload, \"maxFrameBytes\"),\n            max_reassembled_frame_bytes=_optional_int(\n                payload, \"maxReassembledFrameBytes\"\n            ),\n        )\n    if event_type == \"extension_ui_request\":\n        return parse_extension_ui_request(payload)\n    if event_type == \"extension_error\":\n        return parse_extension_error(payload)\n    if event_type == \"agent_start\":\n        return AgentStartEvent()\n    if event_type == \"agent_end\":\n        return AgentEndEvent(\n            messages=parse_agent_messages(","sourceCodeStart":1615,"sourceCodeEnd":1651,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/python/omp-rpc/src/omp_rpc/protocol.py#L1615-L1651","documentation":"When parsing a ReadyEvent, supportedProtocolVersions must be a JSON list of integers. The check explicitly rejects bools (a bool is an int in Python) and non-int members, raising ValueError if any element fails, because version negotiation depends on real integer protocol versions.","triggerScenarios":"A server sends ready.supportedProtocolVersions as strings (e.g. [\"1\", \"2\"]), floats, booleans, a single int instead of a list, or a non-list container like a dict.","commonSituations":"Server implementations serializing versions as strings; JSON encoders emitting 1.0 instead of 1; a naive bool used as a version flag; protocol handshake changes after a server upgrade.","solutions":["Fix the server to emit an array of plain integers, e.g. [1, 2].","Ensure versions are serialized as JSON numbers, not quoted strings.","Verify no encoder converts ints to floats/bools during serialization.","Check client/server protocol versions are compatible."],"exampleFix":"// before\n{\"ready\": {\"supportedProtocolVersions\": [\"1\", \"2\"]}}\n// after\n{\"ready\": {\"supportedProtocolVersions\": [1, 2]}}","handlingStrategy":"validation","validationCode":"versions = ready.get(\"supportedProtocolVersions\")\nif versions is not None and not (isinstance(versions, list) and all(isinstance(v, int) and not isinstance(v, bool) for v in versions)):\n    raise TypeError(\"supportedProtocolVersions must be a list of integers\")","typeGuard":"def is_valid_version_list(ready: dict) -> bool:\n    versions = ready.get(\"supportedProtocolVersions\")\n    return versions is None or (isinstance(versions, list) and all(type(v) is int for v in versions))","tryCatchPattern":"try:\n    ready = parse_ready_event(payload)\nexcept ValueError as exc:\n    raise ProtocolError(f\"bad handshake: {payload!r}\") from exc","preventionTips":["Serialize protocol versions as JSON numbers, never strings or floats.","Remember bool is a subclass of int in Python — use type(v) is int in your own checks.","Add a handshake integration test between client and server."],"tags":["python","rpc","protocol","handshake","schema-validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}