canopy-network/canopy · error · ValueError

Invalid uint64 value: {value}

Error message

Invalid uint64 value: {value}

What it means

format_uint64 encodes a fee/pool numeric component as 8-byte big-endian bytes for state keys. It accepts an int or a decimal string; anything that is not a non-negative integer below 2^64 (including negative ints, floats, non-numeric strings, or string values that overflow uint64) raises ValueError.

Source

Thrown at plugin/python/contract/contract.py:101

def join_len_prefix(*items: Optional[bytes]) -> bytes:
    """Join byte arrays with length prefixes."""
    result = bytearray()
    for item in items:
        if not item:
            continue
        if len(item) > 255:
            raise ValueError(f"Item too long: {len(item)} bytes (max 255)")
        result.append(len(item))
        result.extend(item)
    return bytes(result)


def format_uint64(value: Union[int, str]) -> bytes:
    """Format uint64 as big-endian bytes."""
    if isinstance(value, str):
        value = int(value)
    if not isinstance(value, int) or value < 0 or value >= (1 << 64):
        raise ValueError(f"Invalid uint64 value: {value}")
    return struct.pack('>Q', value)


def key_for_account(address: bytes) -> bytes:
    """Generate state database key for an account."""
    return join_len_prefix(ACCOUNT_PREFIX, address)


def key_for_fee_params() -> bytes:
    """Generate state database key for fee parameters."""
    return join_len_prefix(PARAMS_PREFIX, b"/f/")


def key_for_fee_pool(chain_id: int) -> bytes:
    """Generate state database key for fee pool."""
    return join_len_prefix(POOL_PREFIX, format_uint64(chain_id))

View on GitHub (pinned to ee8197d91d)

Solutions

  1. Validate the value before key construction: confirm it is a non-negative integer < 2**64 (call int(str_value) on strings inside a try/except).
  2. If values come from JSON/RPC, coerce and range-check: value = int(raw); if not (0 <= value < 2**64): reject the tx before building the key.
  3. Log the offending value to identify whether it is a type problem (float/str) or a range problem (>= 2**64), and fix at the source.
  4. For values that can legitimately exceed uint64, change the key scheme to encode a fixed-width or hashed representation instead.

Example fix

// before
key = key_for_fee_pool(amount_float)  # ValueError if float or out of range
// after
value = int(amount_str)
assert 0 <= value < 2**64, f"amount out of uint64 range: {amount_str}"
key = key_for_fee_pool(value)
Defensive patterns

Strategy: type-guard

Validate before calling

def as_uint64(v) -> int:
    if isinstance(v, str):
        v = int(v)
    if not isinstance(v, int) or isinstance(v, bool) or not (0 <= v < 2**64):
        raise ValueError(f"not a uint64: {v!r}")
    return v

Type guard

def is_uint64(v) -> bool:
    if isinstance(v, str):
        try: v = int(v)
        except ValueError: return False
    return isinstance(v, int) and not isinstance(v, bool) and 0 <= v < (1 << 64)

Try / catch

try:
    key = key_for_fee_pool(raw_value)
except ValueError as e:
    if 'Invalid uint64' in str(e):
        return PluginError(1, 'plugin', f'bad amount: {e}')
    raise

Prevention

When it happens

Trigger: Calling key_for_fee_pool() (which calls format_uint64) with a negative number, a float like 1.5, a non-numeric string like 'abc', a None, or a string/int >= 2^64 (e.g. an unvalidated amount from user input).

Common situations: Using a floating-point balance or fee from JSON input; passing a string read from config that contains whitespace or non-digit characters; bigint/overflow values from a client submitting amounts larger than uint64 max.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of canopy-network/canopy@ee8197d91d (2026-09-06). Data as JSON: /api/errors/943ab74b23c04044. Report an issue: GitHub.