can1357/oh-my-pi · error · RpcError

Invalid RPC chunk data

Error message

Invalid RPC chunk data

What it means

The chunk's data field is syntactically invalid base64: base64.b64decode with validate=True raised binascii.Error or ValueError. This is a strict decode — any character outside the standard base64 alphabet (including stray whitespace or newlines embedded in the data string) is rejected. The library raises this before touching reassembly state so bad payloads cannot pollute a pending sequence.

Source

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

            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
            or pending.next_index != index
        ):
            raise RpcError("RPC chunk sequence mismatch")
        pending.chunks.append(chunk)

View on GitHub (pinned to 9690622007)

Solutions

  1. On the sender, use base64.b64encode(...).decode('ascii') exactly — no urlsafe variant, no line wrapping.
  2. Strip or reject any whitespace/newlines in data before sending (validate=True rejects them).
  3. Ensure the data string survives the transport as ASCII (no UTF-8 re-encoding of binary, no truncation).
  4. Catch RpcError and attempt a lenient decode (b64decode without validate, after removing whitespace) in a diagnostic path to see what the sender produced.
  5. Confirm both sides agree on the same base64 alphabet per the omp-rpc protocol.

Example fix

// before
chunk_data = base64.urlsafe_b64encode(payload).decode()  # uses -_ alphabet
client.push(chunk_frame(chunk_data))

// after
chunk_data = base64.b64encode(payload).decode("ascii")  # standard alphabet
client.push(chunk_frame(chunk_data))
Defensive patterns

Strategy: validation

Validate before calling

import base64, binascii
def is_valid_b64(data: str) -> bool:
    if not data or not data.isascii():
        return False
    try:
        base64.b64decode(data, validate=True)
        return True
    except (binascii.Error, ValueError):
        return False

Type guard

def is_ascii_str(value: object) -> TypeGuard[str]:
    return isinstance(value, str) and value.isascii()

Try / catch

try:
    client.push(frame)
except RpcError as exc:
    if str(exc) == "Invalid RPC chunk data":
        data = frame.get("data", "") if isinstance(frame, dict) else ""
        logger.error("non-canonical/invalid base64: prefix=%r", data[:32])
    else:
        raise

Prevention

When it happens

Trigger: push() of an rpc_chunk whose data string contains non-base64 characters (spaces, newlines, URL-safe '-_' instead of '+/', padding errors), or is otherwise rejected by strict base64 decoding.

Common situations: Sender used urlsafe_b64encode while the client expects standard base64; the payload was line-wrapped (PEM style) introducing newlines; a transport mangled the string (truncation, encoding to bytes and back incorrectly); hand-built test frames with placeholder data.

Related errors


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