{"record":{"id":"eacfa7d1a370f0d9","repo":"louislam/uptime-kuma","slug":"no-recipient-or-group-specified","errorCode":null,"errorMessage":"No recipient or group specified","messagePattern":"No recipient or group specified","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/notification-providers/360messenger.js","lineNumber":119,"sourceCode":"                    })\n                );\n\n                return `${okMsg} (Sent to ${groupIds.length} group(s))`;\n            } else if (hasRecipient) {\n                // Send to recipient(s) only\n                await Promise.all(\n                    recipients.map((recipient) => {\n                        const data = {\n                            phonenumber: recipient,\n                            text: message,\n                        };\n                        return axios.post(\"https://api.360messenger.com/v2/sendMessage\", data, config);\n                    })\n                );\n\n                return `${okMsg} (Sent to ${recipients.length} recipient(s))`;\n            } else {\n                throw new Error(\"No recipient or group specified\");\n            }\n        } catch (error) {\n            this.throwGeneralAxiosError(error);\n        }\n    }\n\n    /**\n     * Apply template with variables\n     * @param {string} template - Template string\n     * @param {string} msg - Default message\n     * @param {object} monitorJSON - Monitor data\n     * @param {object} heartbeatJSON - Heartbeat data\n     * @returns {string} Formatted message\n     */\n    applyTemplate(template, msg, monitorJSON, heartbeatJSON) {\n        try {\n            // Simple template replacement\n            let result = template;","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/louislam/uptime-kuma/blob/6b5ea0155793e666666745fb8d6fef1e829543a2/server/notification-providers/360messenger.js#L101-L137","documentation":"360messenger.js:118-120. After normalizing both recipient phone numbers and group IDs (supporting comma/semicolon lists and arrays), if BOTH lists are empty the send has no destination, so it throws rather than making a pointless API call.","triggerScenarios":"Notification saved with blank Whatsapp360messengerRecipient AND no Whatsapp360messengerGroupIds/GroupId; field was populated only with whitespace or a lone separator (';' or ','); a migration/import left the columns null.","commonSituations":"User configured the provider but never filled in a destination; recipient field renamed in a schema migration and the old value was not carried over; front-end validation allowed an empty submit.","solutions":["Open the notification settings and set at least one recipient phone number or group id.","Strip stray separators: ensure the field contains actual values, not just ',' or ';'.","If using group IDs, verify Whatsapp360messengerGroupIds is an array or a delimited string with real entries.","Add front-end/DB validation so the provider cannot be saved without a destination."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate that at least one destination exists before calling send\nfunction hasDestination(notification) {\n    const recipient = (notification.Whatsapp360messengerRecipient || '').split(/[;,]/).map(s=>s.trim()).filter(Boolean);\n    const groups = [].concat(notification.Whatsapp360messengerGroupIds || notification.Whatsapp360messengerGroupId || [])\n        .map(g => typeof g === 'object' ? g?.id : g).map(String).map(s=>s.trim()).filter(Boolean);\n    return recipient.length + groups.length > 0;\n}\nif (!hasDestination(notification)) throw new Error('No recipient or group specified');","typeGuard":"function isNonEmptyDestinationList(notification) {\n    return Boolean(notification) && (\n        (notification.Whatsapp360messengerRecipient || '').trim() !== '' ||\n        Boolean(notification.Whatsapp360messengerGroupIds?.length) ||\n        Boolean(notification.Whatsapp360messengerGroupId)\n    );\n}","tryCatchPattern":"try { await provider.send(notification, msg, monitorJSON, heartbeatJSON); }\ncatch (e) {\n    if (e.message === 'No recipient or group specified') {\n        // config error — disable the provider or alert the user, do not retry blindly\n        throwGeneralAxiosError(e);\n    }\n}","preventionTips":["Validate destinations on save in the UI, not at send time.","After schema migrations, run a consistency check that all notification rows have non-empty destinations."],"tags":["notification","validation","whatsapp","config"],"backgroundTag":null,"analyzedSha":"6b5ea0155793e666666745fb8d6fef1e829543a2","analyzedAt":"2026-08-12T23:42:12.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}