{"record":{"id":"943ab74b23c04044","repo":"canopy-network/canopy","slug":"invalid-uint64-value-value","errorCode":null,"errorMessage":"Invalid uint64 value: {value}","messagePattern":"Invalid uint64 value: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"plugin/python/contract/contract.py","lineNumber":101,"sourceCode":"def join_len_prefix(*items: Optional[bytes]) -> bytes:\n    \"\"\"Join byte arrays with length prefixes.\"\"\"\n    result = bytearray()\n    for item in items:\n        if not item:\n            continue\n        if len(item) > 255:\n            raise ValueError(f\"Item too long: {len(item)} bytes (max 255)\")\n        result.append(len(item))\n        result.extend(item)\n    return bytes(result)\n\n\ndef format_uint64(value: Union[int, str]) -> bytes:\n    \"\"\"Format uint64 as big-endian bytes.\"\"\"\n    if isinstance(value, str):\n        value = int(value)\n    if not isinstance(value, int) or value < 0 or value >= (1 << 64):\n        raise ValueError(f\"Invalid uint64 value: {value}\")\n    return struct.pack('>Q', value)\n\n\ndef key_for_account(address: bytes) -> bytes:\n    \"\"\"Generate state database key for an account.\"\"\"\n    return join_len_prefix(ACCOUNT_PREFIX, address)\n\n\ndef key_for_fee_params() -> bytes:\n    \"\"\"Generate state database key for fee parameters.\"\"\"\n    return join_len_prefix(PARAMS_PREFIX, b\"/f/\")\n\n\ndef key_for_fee_pool(chain_id: int) -> bytes:\n    \"\"\"Generate state database key for fee pool.\"\"\"\n    return join_len_prefix(POOL_PREFIX, format_uint64(chain_id))\n\n","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/canopy-network/canopy/blob/ee8197d91dd410f6592cb650a94c925ee6dc8bad/plugin/python/contract/contract.py#L83-L119","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["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).","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.","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.","For values that can legitimately exceed uint64, change the key scheme to encode a fixed-width or hashed representation instead."],"exampleFix":"// before\nkey = key_for_fee_pool(amount_float)  # ValueError if float or out of range\n// after\nvalue = int(amount_str)\nassert 0 <= value < 2**64, f\"amount out of uint64 range: {amount_str}\"\nkey = key_for_fee_pool(value)","handlingStrategy":"type-guard","validationCode":"def as_uint64(v) -> int:\n    if isinstance(v, str):\n        v = int(v)\n    if not isinstance(v, int) or isinstance(v, bool) or not (0 <= v < 2**64):\n        raise ValueError(f\"not a uint64: {v!r}\")\n    return v","typeGuard":"def is_uint64(v) -> bool:\n    if isinstance(v, str):\n        try: v = int(v)\n        except ValueError: return False\n    return isinstance(v, int) and not isinstance(v, bool) and 0 <= v < (1 << 64)","tryCatchPattern":"try:\n    key = key_for_fee_pool(raw_value)\nexcept ValueError as e:\n    if 'Invalid uint64' in str(e):\n        return PluginError(1, 'plugin', f'bad amount: {e}')\n    raise","preventionTips":["Range-check amounts from JSON/RPC before building state keys.","Convert config strings to int at load time.","Never pass floats where uint64 is expected — round or reject upstream.","Add property-based tests over the uint64 boundary (0, 2**64-1, 2**64)."],"tags":["python","validation","uint64","state-keys"],"backgroundTag":"invalid-argument-value","analyzedSha":"ee8197d91dd410f6592cb650a94c925ee6dc8bad","analyzedAt":"2026-09-06T09:30:15.973Z","contentChangedAt":"2026-09-06T09:30:15.973Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}