HelloZeroNet/ZeroNet · error · Exception

Invalid data type: %s

Error message

Invalid data type: %s

What it means

packPiecefield in BigfilePiecefield.py compresses a piecefield (bytes of b'\x00'/b'\x01' flags describing downloaded big-file pieces) into run-length encoded 16-bit words. It raises Exception("Invalid data type: %s") when the input is neither bytes nor bytearray — the compressor refuses to guess how to encode other types.

Source

Thrown at plugins/Bigfile/BigfilePiecefield.py:6

import array


def packPiecefield(data):
    if not isinstance(data, bytes) and not isinstance(data, bytearray):
        raise Exception("Invalid data type: %s" % type(data))

    res = []
    if not data:
        return array.array("H", b"")

    if data[0] == b"\x00":
        res.append(0)
        find = b"\x01"
    else:
        find = b"\x00"
    last_pos = 0
    pos = 0
    while 1:
        pos = data.find(find, pos)
        if find == b"\x00":
            find = b"\x01"
        else:
            find = b"\x00"

View on GitHub (pinned to 454c0b2e7e)

Solutions

  1. Convert the value first: data = data.encode() if isinstance(data, str) else bytes(data).
  2. Check where the piecefield is stored/loaded (json/DB) and preserve it as bytes (e.g. store base64).
  3. Fix the API caller to pass the raw bytes from Piecefield.tobytes().
  4. Add an isinstance check at the boundary before packing.

Example fix

// before
packed = packPiecefield(piecefield_data)  # piecefield_data is str from JSON
// after
if isinstance(piecefield_data, str):
    piecefield_data = piecefield_data.encode("latin1")
packed = packPiecefield(piecefield_data)
Defensive patterns

Strategy: type-guard

Validate before calling

if not isinstance(data, (bytes, bytearray)):
    data = data.encode("latin1") if isinstance(data, str) else bytes(data)

Type guard

def is_piecefield_bytes(data):
    return isinstance(data, (bytes, bytearray))

Try / catch

try:
    packed = packPiecefield(data)
except Exception as e:
    if "Invalid data type" in str(e):
        packed = packPiecefield(data.encode("latin1"))
    else:
        raise

Prevention

When it happens

Trigger: Calling packPiecefield (directly or via Piecefield.pack()/frombytes->pack chains) with a str, list, array, or None instead of bytes/bytearray — typically a piecefield stored/loaded through a channel that decoded it (e.g. JSON turning bytes into str).

Common situations: Piecefields persisted to sites.json/SQLite as text and read back as str; receiving piecefield data over the ZeroNet protocol where decoding changed the type; passing memoryview or array('H') directly.

Related errors


AI-assisted analysis of HelloZeroNet/ZeroNet@454c0b2e7e (2026-09-02). Data as JSON: /api/errors/2fb148fc35fbb3c4. Report an issue: GitHub.