can1357/oh-my-pi · error · RpcError

Invalid RPC chunk metadata

Error message

Invalid RPC chunk metadata

What it means

An rpc_chunk frame carrying base64 payload metadata failed structural validation: chunkId/index/count/byteLength are missing or of wrong type, index >= count, byteLength is smaller than one frame or larger than the reassembly cap, or the data field is missing/empty/not a string. The library validates metadata before decoding so corrupt sequences are rejected early and cannot corrupt the pending reassembly state.

Source

Thrown at python/omp-rpc/src/omp_rpc/client.py:176

            not isinstance(chunk_id, str)
            or not chunk_id
            or len(chunk_id) > 128
            or not isinstance(index, int)
            or isinstance(index, bool)
            or not isinstance(count, int)
            or isinstance(count, bool)
            or not isinstance(byte_length, int)
            or isinstance(byte_length, bool)
            or index < 0
            or count < 2
            or count > max_chunk_count
            or index >= count
            or byte_length < _MAX_RPC_FRAME_BYTES
            or byte_length > _MAX_RPC_REASSEMBLED_BYTES
            or not isinstance(data, str)
            or not data
        ):
            raise RpcError("Invalid RPC chunk metadata")
        try:
            chunk = base64.b64decode(data, validate=True)
        except (binascii.Error, ValueError) as exc:
            raise RpcError("Invalid RPC chunk data") from exc
        if base64.b64encode(chunk).decode("ascii") != data:
            raise RpcError("Invalid RPC chunk data")
        if len(chunk) > _RPC_CHUNK_PAYLOAD_BYTES:
            raise RpcError("RPC chunk payload exceeds the transport limit")

        if self._pending is None:
            if index != 0:
                raise RpcError("RPC chunk sequence must start at index 0")
            self._pending = _PendingRpcChunks(chunk_id, count, byte_length)
        pending = self._pending
        if (
            pending.chunk_id != chunk_id
            or pending.count != count
            or pending.byte_length != byte_length

View on GitHub (pinned to 9690622007)

Solutions

  1. Ensure the sender emits all required chunk fields: chunkId, index, count, byteLength, and non-empty base64 data.
  2. Verify the sender's byteLength matches the total UTF-8 size of the reassembled payload and is within the transport limits.
  3. Confirm index values are 0-based, strictly increasing, and index < count.
  4. Check that both ends use the same omp-rpc protocol version and chunking scheme.
  5. Catch RpcError and log the offending frame's keys to identify which metadata field is wrong.

Example fix

// before
client.push({"type": "rpc_chunk", "data": base64_data})  # missing metadata

// after
client.push({
    "type": "rpc_chunk",
    "chunkId": chunk_id,
    "index": i,
    "count": total_chunks,
    "byteLength": total_bytes,
    "data": base64_data,
})
Defensive patterns

Strategy: validation

Validate before calling

def validate_chunk_meta(frame: dict) -> bool:
    return (
        isinstance(frame.get("chunkId"), str)
        and isinstance(frame.get("index"), int)
        and isinstance(frame.get("count"), int)
        and isinstance(frame.get("byteLength"), int)
        and 0 <= frame["index"] < frame["count"]
        and isinstance(frame.get("data"), str)
        and bool(frame["data"])
    )

Type guard

def is_rpc_chunk(value: object) -> TypeGuard[dict]:
    return (
        isinstance(value, dict)
        and value.get("type") == "rpc_chunk"
        and isinstance(value.get("chunkId"), str)
        and isinstance(value.get("data"), str)
    )

Try / catch

try:
    client.push(frame)
except RpcError as exc:
    if "chunk" in str(exc):
        logger.error("bad chunk from sender: keys=%s", sorted(frame) if isinstance(frame, dict) else type(frame))
        request_resend()
    else:
        raise

Prevention

When it happens

Trigger: push({"type": "rpc_chunk", ...}) where any of chunkId/index/count/byteLength is absent or mistyped, index equals or exceeds count, byteLength < _MAX_RPC_FRAME_BYTES, byteLength > _MAX_RPC_REASSEMBLED_BYTES, or data is missing, empty, or not a string.

Common situations: A sender built the chunk manually and forgot required fields; a truncated/rewritten frame from an intermediary; protocol version mismatch where the peer encodes chunks with different field names or semantics; a sender that chunked but never set byteLength correctly.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/590f13148d32605a. Report an issue: GitHub.