moeru-ai/airi · warning
no consumer registered for event delivery
Error message
no consumer registered for event delivery
What it means
server-runtime routes events between authenticated peers. When an event's resolved delivery mode is 'consumer' or 'consumer-group', selectConsumer must find a peer that registered as a consumer for that event name (via the module:consumer:register message). If none is registered at delivery time, this warning logs and the event is dropped; when delivery.required is set, the sender additionally receives a noConsumerRegistered error response correlated by event id.
Source
Thrown at packages/server-runtime/src/index.ts:900
const delivery = shouldBypass ? undefined : resolveEventDelivery(event)
const effectiveRoutingMiddleware = shouldBypass ? [] : routingMiddleware
const decision = forEachEventMiddlewares({
event,
fromPeer: p,
peers,
destinations,
middleware: effectiveRoutingMiddleware,
})
if (decision?.type === 'drop') {
logger.withFields({ peer: peer.id, peerName: p.name, event }).debug('routing dropped event')
return
}
const selectedConsumer = selectConsumer(event, peer.id, delivery)
if (delivery && (delivery.mode === 'consumer' || delivery.mode === 'consumer-group')) {
if (!selectedConsumer) {
logger.withFields({ peer: peer.id, peerName: p.name, event, delivery }).warn('no consumer registered for event delivery')
if (delivery.required) {
send(peer, RESPONSES.error(ServerErrorMessages.noConsumerRegistered, event.metadata?.event.id))
}
return
}
try {
logger.withFields({
fromPeer: peer.id,
fromPeerName: p.name,
toPeer: selectedConsumer.peer.id,
toPeerName: selectedConsumer.name,
event,
delivery,
}).debug('sending event to selected consumer')
selectedConsumer.peer.send(payload)
}View on GitHub (pinned to 677329427f)
Solutions
- Make the consumer register (module:consumer:register for that event name) before the producer emits, or gate emitting on consumer readiness
- Verify the event name string matches exactly on both peers (case-sensitive) and the payload contract is shared
- Keep delivery.required = true on the emitting side so drops surface as error responses you can handle instead of silent loss
- Buffer or retry emissions that arrive during consumer reconnect windows
Example fix
// before (producer emits immediately on connect)
peer.send(createEvent('assistant:speak', payload, { delivery: { mode: 'consumer', required: true } }))
// after (wait until a consumer is registered)
await waitForConsumerRegistered('assistant:speak')
peer.send(createEvent('assistant:speak', payload, { delivery: { mode: 'consumer', required: true } })) Defensive patterns
Strategy: validation
Validate before calling
// before emitting a consumer-routed event
if (!(await hasConsumerFor('assistant:speak'))) {
throw new Error(`no consumer registered for assistant:speak`)
}
peer.send(createEvent('assistant:speak', payload, { delivery: { mode: 'consumer', required: true } })) Try / catch
// as the emitting peer, handle the required-delivery error response
peer.onResponse((response) => {
if (response.error === ServerErrorMessages.noConsumerRegistered) {
// queue and retry after the consumer reconnects/registers
pendingEvents.push(originalEvent)
}
}) Prevention
- Register consumers (module:consumer:register) before producers start emitting
- Share event-name constants between peers to prevent typo drift
- Keep delivery.required=true in development so missing consumers surface immediately
- Buffer events during consumer reconnect windows instead of relying on the drop
When it happens
Trigger: Emitting a consumer-routed event before any peer sent module:consumer:register for that exact event name; the consumer peer disconnected after registering; an event-name mismatch (typo, renamed constant) so the registration never matches.
Common situations: Startup race where a producer emits before the consumer service finishes registering; consumer crash/reconnect leaving a window with no subscribers; renaming an event constant on one side of the contract only.
Related errors
AI-assisted analysis of moeru-ai/airi@677329427f (2026-08-18).
Data as JSON: /api/errors/2eaebc2b06799b88.
Report an issue: GitHub.