hcengineering/platform · error
'subscriptions' is missing
Error message
'subscriptions' is missing
What it means
The pod-notification push handler responds HTTP 400 with { err: "'subscriptions' is missing" } when req.body.subscriptions is undefined. Even with valid data, the service needs the array of PushSubscription endpoints to deliver to; without it there is nothing to send, so it rejects the request. Note: if web-push was never initialized, the handler instead returns an empty result rather than this error.
Source
Thrown at services/notification/pod-notification/src/main.ts:74
return true
}
const endpoints: Endpoint[] = [
{
endpoint: '/web-push',
type: 'post',
handler: async (req, res) => {
if (!checkAuth(req, res)) {
return
}
const data: PushData | undefined = req.body?.data
if (data === undefined) {
res.status(400).send({ err: "'data' is missing" })
return
}
const subscriptions: PushSubscription[] | undefined = req.body?.subscriptions
if (subscriptions === undefined) {
res.status(400).send({ err: "'subscriptions' is missing" })
return
}
if (!webpushInitDone) {
res.json({ result: [] }).end()
return
}
const result = await sendPushToSubscription(ctx, subscriptions, data)
res.json({ result }).end()
}
}
]
const server = listen(createServer(endpoints), config.Port, undefined, () => {
ctx.info('Notification service listening', { port: config.Port })
})
const shutdown = (): void => {View on GitHub (pinned to 63e28dc964)
Solutions
- Include 'subscriptions' as an array in the JSON body: {"data":{...},"subscriptions":[{"endpoint":..., "keys":{...}}]}.
- If you have zero subscriptions, send an empty array rather than omitting the field.
- Verify each item is a PushSubscription (with endpoint and keys.p256dh/keys.auth) matching the service's expected shape.
- Fix field-name mismatches — the service reads exactly req.body.subscriptions.
Example fix
// before
post(pushUrl, { data, subscription: sub })
// after
post(pushUrl, { data, subscriptions: [sub] }) Defensive patterns
Strategy: validation
Validate before calling
function hasSubscriptions(body: unknown): boolean {
const s = (body as any)?.subscriptions
return Array.isArray(s) && s.every(x => typeof (x as any)?.endpoint === 'string' && (x as any)?.keys?.p256dh && (x as any)?.keys?.auth)
}
if (!hasSubscriptions(payload)) throw new Error("push request requires a 'subscriptions' array of valid PushSubscription objects") Type guard
function isPushSubscription(v: unknown): v is { endpoint: string; keys: { p256dh: string; auth: string } } {
const s = v as any
return typeof s?.endpoint === 'string' && typeof s?.keys?.p256dh === 'string' && typeof s?.keys?.auth === 'string'
} Try / catch
const res = await fetch(pushUrl, opts)
if (res.status === 400) {
const { err } = await res.json()
if (err?.includes("'subscriptions' is missing")) throw new Error('push payload must include a subscriptions array (send [] if none)')
} Prevention
- Always send subscriptions as an array, even when empty
- Validate each PushSubscription (endpoint + keys.p256dh + keys.auth) before batching
- Prune expired subscriptions from storage so valid arrays are maintained
When it happens
Trigger: POST with body.data present but no 'subscriptions' key, subscriptions spelled differently ('subs', 'endpoints'), or subscriptions passed as a single object instead of an array.
Common situations: Client code updated to send data but subscription storage not wired in; sending one subscription object directly instead of wrapping it in an array; database of subscriptions empty leading code to omit the field instead of sending []; migrating from another push service with a different field name.
Related errors
- 'data' is missing
- Failed to load server config
- getDisplayMedia not supported
- No screen access granted
- 'from' is missing
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/955fad3288db56ca.
Report an issue: GitHub.