bytedance/deer-flow · error · ValueError
expected exactly 32 bytes
Error message
expected exactly 32 bytes
What it means
The hex fallback path of _parse_32_bytes decoded successfully but produced a byte string whose length is not exactly 32. Nostr secrets and pubkeys are 32 bytes (64 hex chars), so a 63/65/66-char hex value or a short fragment raises this ValueError.
Source
Thrown at backend/app/channels/buzz_nostr.py:80
bits += 5
if bits >= 8:
bits -= 8
out.append((acc >> bits) & 0xFF)
if len(out) != 32:
raise ValueError(f"expected 32-byte payload in {value!r}")
return bytes(out)
def _parse_32_bytes(value: str, bech_hrp: str) -> bytes:
value = value.strip()
if value.lower().startswith(f"{bech_hrp}1"):
return _bech32_decode(bech_hrp, value.lower())
try:
raw = bytes.fromhex(value)
except ValueError as exc:
raise ValueError(f"expected 64-hex or {bech_hrp}1... value") from exc
if len(raw) != 32:
raise ValueError("expected exactly 32 bytes")
return raw
def parse_private_key(value: str) -> NostrKeys:
secret = _parse_32_bytes(value, "nsec")
coincurve = _require_coincurve()
pubkey = coincurve.PrivateKey(secret).public_key.format(compressed=True)[1:]
return NostrKeys(secret=secret, pubkey_hex=pubkey.hex())
def parse_pubkey(value: str) -> str:
return _parse_32_bytes(value, "npub").hex()
def event_id(pubkey_hex: str, created_at: int, kind: int, tags: list[list[str]], content: str) -> str:
payload = json.dumps([0, pubkey_hex, created_at, kind, tags, content], separators=(",", ":"), ensure_ascii=False)
return hashlib.sha256(payload.encode()).hexdigest()
View on GitHub (pinned to 1dd6ba1acb)
Solutions
- Count the hex characters — must be exactly 64 (32 bytes).
- Re-copy the full key from the source; a single dropped char is the usual cause.
- If your value is a different length, you are holding the wrong secret — re-export the Nostr key.
Example fix
# before (63 chars — truncated) private_key: "4c0a5c...e" # one char short # after private_key: "4c0a5c...e3" # exactly 64 hex chars
Defensive patterns
Strategy: validation
Validate before calling
def hex_is_32_bytes(value: str) -> bool:
v = value.strip()
return len(v) == 64 and all(c in '0123456789abcdefABCDEF' for c in v) Try / catch
try:
parse_private_key(raw)
except ValueError as e:
if 'exactly 32 bytes' in str(e):
raise ConfigError('key must be 64 hex chars — likely truncated paste') from e
raise Prevention
- Assert len(hex) == 64 in provisioning scripts before writing config.
- Use secret managers that store fixed-size values rather than free-form strings.
- Watch for clipboard tools that drop leading zeros.
When it happens
Trigger: A hex value with one character dropped or added (odd or wrong-length), a 32-hex-char (16-byte) fragment, or a full 64-byte (128-hex) key pasted where a 32-byte one is expected.
Common situations: Clipboard truncation losing one character; pasting a signature or a sha256 digest pair instead of the key; mixing up compressed/uncompressed key formats from other crypto tooling.
Related errors
- expected 64-hex or {bech_hrp}1... value
- channels.buzz.relay_url must be a ws:// or wss:// URL
- not bech32: {value!r}
- expected {expected_hrp!r} bech32, got {hrp!r}
- invalid bech32 character in {value!r}
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/a41a71aaef3fb609.
Report an issue: GitHub.