Skip to content

fix: handle missing bolt11 in CLN list_payments for keysend/BOLT12#307

Merged
fusion44 merged 1 commit into
fusion44:devfrom
sharpone74:fix-cln-keyerror-listpays
May 12, 2026
Merged

fix: handle missing bolt11 in CLN list_payments for keysend/BOLT12#307
fusion44 merged 1 commit into
fusion44:devfrom
sharpone74:fix-cln-keyerror-listpays

Conversation

@sharpone74
Copy link
Copy Markdown
Contributor

Follow-up to #290 — same class of bug, different code path.

list_payments() in app/lightning/impl/cln_jrpc.py unconditionally indexed p["bolt11"] for any incomplete payment:

if include_incomplete:
    b11_decoded = await self._decode_bolt11_cached(p["bolt11"])
    p["amount_msat"] = b11_decoded.num_msat
    pays.append(Payment.from_cln_jrpc(p))

CLN's listpays does not include bolt11 for keysend payments or BOLT12 offer payments, so any node that has ever made one of those hits a KeyError: 'bolt11'. Because list_payments is decorated with @logger.catch, the exception is swallowed and the function returns None. Its caller list_all_tx() then crashes with TypeError: 'NoneType' object is not iterable, and the /lightning/list-all-tx endpoint returns HTTP 500 — breaking the Transactions view in the web UI on every load.

Fix

Guard the bolt11 decode the same way #290 guards invoice fields:

  • Only call _decode_bolt11_cached when bolt11 is actually present.
  • If bolt11 is missing and amount_msat is missing, fall back to amount_sent_msat (or 0) so Payment.from_cln_jrpc still sees the field it expects and the payment still shows up in the list.
  • If amount_msat is already populated by CLN (the common case for keysend), skip the decode entirely.

Reproduction

  • RaspiBlitz v1.12.1 / Core Lightning v25.12.1
  • At least one keysend or BOLT12 payment in payment history
  • Open the Transactions tab in the web UI → 500
  • Stack trace in journalctl -u blitzapi:
    File ".../cln_jrpc.py", line 418, in list_payments
    KeyError: 'bolt11'
    list_payments() returned None
    File ".../cln_jrpc.py", line 250, in list_all_tx
    TypeError: 'NoneType' object is not iterable
    GET /api/lightning/list-all-tx?reversed=true HTTP/1.0 500
    

After the patch, list_payments returns the full list including keysend/BOLT12 entries, and the Transactions view loads.

Notes

Follow-up to fusion44#290 — same class of bug, different code path.

list_payments() in cln_jrpc.py unconditionally indexed p["bolt11"] for any
incomplete payment, causing a KeyError -> the function returned None and
then list_all_tx() crashed with `TypeError: 'NoneType' object is not
iterable`, returning HTTP 500 to the Transactions view.

CLN's `listpays` does not include `bolt11` for keysend payments or for
BOLT12 offer payments, so any node that has ever made one of those will
hit this on every Transactions load.

Fix: guard the bolt11 decode the same way fusion44#290 guards invoice fields —
only decode when bolt11 is present, and fall back to amount_sent_msat
when neither bolt11 nor amount_msat are available, so the payment still
shows up in the list.

Reproduced on RaspiBlitz v1.12.1 with Core Lightning v25.12.1 and a
keysend payment in history.
@fusion44 fusion44 merged commit d415fb3 into fusion44:dev May 12, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants