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
- Collect recipient addresses as npub1... strings only (public keys).
- Strip empty lines and trim each line in the recipients list before decoding.
- If you only have hex public keys, convert them to npub with nip19.npubEncode before saving.
- 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
- Filter blank lines before decoding recipients.
- Validate npub1 prefix before invoking nip19.decode.
- Keep private (nsec) values out of the recipient list.
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
- Failed to decode private key for sender ${sender}: ${error.m
- Failed to create gift-wrapped event for recipient: ${error.m
- Error decoding recipient ${recipient}: ${error}
- Invalid Docker response, is it Docker really a daemon?
- domain_expiry_unsupported_monitor_type
AI-assisted analysis of louislam/uptime-kuma@6b5ea01557 (2026-08-12).
Data as JSON: /api/errors/9807e2832683618c.
Report an issue: GitHub.