{"record":{"id":"72caba71453ee6e7","repo":"bytedance/deer-flow","slug":"expected-32-byte-payload-in-value-r","errorCode":null,"errorMessage":"expected 32-byte payload in {value!r}","messagePattern":"expected 32-byte payload in (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"backend/app/channels/buzz_nostr.py","lineNumber":67,"sourceCode":"    if hrp != expected_hrp:\n        raise ValueError(f\"expected {expected_hrp!r} bech32, got {hrp!r}\")\n    try:\n        data = [_BECH32_CHARSET.index(c) for c in data_part]\n    except ValueError as exc:\n        raise ValueError(f\"invalid bech32 character in {value!r}\") from exc\n    hrp_expanded = [ord(c) >> 5 for c in hrp] + [0] + [ord(c) & 31 for c in hrp]\n    if _bech32_polymod(hrp_expanded + data) != 1:\n        raise ValueError(f\"bad bech32 checksum in {value!r}\")\n    acc = bits = 0\n    out = bytearray()\n    for v in data[:-6]:\n        acc = (acc << 5) | v\n        bits += 5\n        if bits >= 8:\n            bits -= 8\n            out.append((acc >> bits) & 0xFF)\n    if len(out) != 32:\n        raise ValueError(f\"expected 32-byte payload in {value!r}\")\n    return bytes(out)\n\n\ndef _parse_32_bytes(value: str, bech_hrp: str) -> bytes:\n    value = value.strip()\n    if value.lower().startswith(f\"{bech_hrp}1\"):\n        return _bech32_decode(bech_hrp, value.lower())\n    try:\n        raw = bytes.fromhex(value)\n    except ValueError as exc:\n        raise ValueError(f\"expected 64-hex or {bech_hrp}1... value\") from exc\n    if len(raw) != 32:\n        raise ValueError(\"expected exactly 32 bytes\")\n    return raw\n\n\ndef parse_private_key(value: str) -> NostrKeys:\n    secret = _parse_32_bytes(value, \"nsec\")","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/app/channels/buzz_nostr.py#L49-L85","documentation":"After a valid checksum, the bech32 data part is converted from 5-bit groups back to bytes; the decoder requires exactly 32 bytes because Nostr keys are 32-byte values. If the decoded length differs (too short/long), this ValueError is raised — a structurally valid bech32 string of the wrong length, which for real nsec/npub keys should never happen.","triggerScenarios":"A bech32 string with a correct checksum but a payload that decodes to something other than 32 bytes — typically a hand-crafted value, a key from a different scheme that happens to carry the nsec/npub hrp, or a value padded/extended in a checksum-consistent way.","commonSituations":"Very rare in practice; usually indicates someone generated a test/garbage value, or a tool emitted a non-standard encoding. Real nsec1/npub1 keys from any Nostr client are always 32 bytes.","solutions":["Generate the key with a standard Nostr client or `python -c \"import secrets; print(secrets.token_hex(32))\"` and use the hex form.","Do not hand-craft or modify bech32 strings.","If a tool produced this value, report the encoding bug to that tool and re-export the key."],"exampleFix":"# generate a fresh key as hex and use it directly\npython -c \"import secrets; print(secrets.token_hex(32))\"\n# -> put the 64-char hex output into channels.buzz.private_key","handlingStrategy":"validation","validationCode":"def is_32byte_bech32(value: str, hrp: str) -> bool:\n    v = value.strip().lower()\n    if not (v.startswith(hrp + '1') and '1' in v[len(hrp) + 1:]):\n        return False\n    data_len = len(v.rsplit('1', 1)[-1]) - 6  # minus checksum\n    return data_len * 5 // 8 == 32","typeGuard":null,"tryCatchPattern":"try:\n    keys = parse_private_key(raw)\nexcept ValueError:\n    # generate a fresh, known-good key rather than debugging a hand-made one\n    raw = secrets.token_hex(32)\n    keys = parse_private_key(raw)","preventionTips":["Never hand-craft bech32 values; always generate with standard tooling.","Add a smoke test that parses a generated key end-to-end at channel startup."],"tags":["buzz","nostr","bech32","validation"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}