louislam/uptime-kuma · warning · Error

Recipient ${recipient} is not an npub

Error message

Recipient ${recipient} is not an npub

What it means

Inside Nostr.getPublicKeys, each recipient is decoded with nip19.decode; if decoding succeeds but the result type is not 'npub' (for example it is an nsec, note, nprofile, or nrelay), this Error is thrown. It is immediately caught by the surrounding per-recipient catch (line 107) and re-wrapped as 'Error decoding recipient <recipient>: <error>', so in practice the outer message is what surfaces.

Source

Thrown at server/notification-providers/nostr.js:105

        }
    }

    /**
     * Get public keys for recipients
     * @param {string} recipients Newline delimited list of recipients
     * @returns {Promise<nip19.DecodeResult[]>} Public keys
     */
    async getPublicKeys(recipients) {
        const recipientsList = recipients.split("\n");
        const publicKeys = [];
        for (const recipient of recipientsList) {
            try {
                const recipientDecodeResult = await nip19.decode(recipient);
                const { type, data } = recipientDecodeResult;
                if (type === "npub") {
                    publicKeys.push(data);
                } else {
                    throw new Error(`Recipient ${recipient} is not an npub`);
                }
            } catch (error) {
                throw new Error(`Error decoding recipient ${recipient}: ${error}`);
            }
        }
        return publicKeys;
    }
}

module.exports = Nostr;

View on GitHub (pinned to 6b5ea01557)

Solutions

  1. Collect recipient addresses as npub1... strings only (public keys).
  2. Strip empty lines and trim each line in the recipients list before decoding.
  3. If you only have hex public keys, convert them to npub with nip19.npubEncode before saving.
  4. Treat the surfaced 'Error decoding recipient' as pointing at the specific offending entry.
Defensive patterns

Strategy: validation

Validate before calling

for (const r of recipientsList) {
    const t = r.trim();
    if (!t) continue;
    if (!t.startsWith("npub1")) {
        throw new Error(`Recipient '${t}' is not an npub1... public key`);
    }
}

Type guard

/** @param {string} s */
function looksLikeNpub(s) {
    return typeof s === "string" && s.startsWith("npub1") && s.length > 10;
}

Prevention

When it happens

Trigger: A recipient entry is a valid bech32 entity but the wrong kind: an nsec1 (private key) instead of npub1, an nprofile1, a note1 event id, or any other NIP-19 entity that decodes but is not a public key.

Common situations: User pasted their own private key (nsec) into the recipient list; pasted a profile/event id; mixed up public and private key fields when distributing recipients.

Related errors


AI-assisted analysis of louislam/uptime-kuma@6b5ea01557 (2026-08-12). Data as JSON: /api/errors/9807e2832683618c. Report an issue: GitHub.