{"record":{"id":"2eaebc2b06799b88","repo":"moeru-ai/airi","slug":"no-consumer-registered-for-event-delivery","errorCode":null,"errorMessage":"no consumer registered for event delivery","messagePattern":"no consumer registered for event delivery","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/server-runtime/src/index.ts","lineNumber":900,"sourceCode":"    const delivery = shouldBypass ? undefined : resolveEventDelivery(event)\n    const effectiveRoutingMiddleware = shouldBypass ? [] : routingMiddleware\n    const decision = forEachEventMiddlewares({\n      event,\n      fromPeer: p,\n      peers,\n      destinations,\n      middleware: effectiveRoutingMiddleware,\n    })\n\n    if (decision?.type === 'drop') {\n      logger.withFields({ peer: peer.id, peerName: p.name, event }).debug('routing dropped event')\n      return\n    }\n\n    const selectedConsumer = selectConsumer(event, peer.id, delivery)\n    if (delivery && (delivery.mode === 'consumer' || delivery.mode === 'consumer-group')) {\n      if (!selectedConsumer) {\n        logger.withFields({ peer: peer.id, peerName: p.name, event, delivery }).warn('no consumer registered for event delivery')\n        if (delivery.required) {\n          send(peer, RESPONSES.error(ServerErrorMessages.noConsumerRegistered, event.metadata?.event.id))\n        }\n        return\n      }\n\n      try {\n        logger.withFields({\n          fromPeer: peer.id,\n          fromPeerName: p.name,\n          toPeer: selectedConsumer.peer.id,\n          toPeerName: selectedConsumer.name,\n          event,\n          delivery,\n        }).debug('sending event to selected consumer')\n\n        selectedConsumer.peer.send(payload)\n      }","sourceCodeStart":882,"sourceCodeEnd":918,"githubUrl":"https://github.com/moeru-ai/airi/blob/677329427f32468c74b17f3ec47eeca4e05bec65/packages/server-runtime/src/index.ts#L882-L918","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before (producer emits immediately on connect)\npeer.send(createEvent('assistant:speak', payload, { delivery: { mode: 'consumer', required: true } }))\n\n// after (wait until a consumer is registered)\nawait waitForConsumerRegistered('assistant:speak')\npeer.send(createEvent('assistant:speak', payload, { delivery: { mode: 'consumer', required: true } }))","handlingStrategy":"validation","validationCode":"// before emitting a consumer-routed event\nif (!(await hasConsumerFor('assistant:speak'))) {\n  throw new Error(`no consumer registered for assistant:speak`)\n}\npeer.send(createEvent('assistant:speak', payload, { delivery: { mode: 'consumer', required: true } }))","typeGuard":null,"tryCatchPattern":"// as the emitting peer, handle the required-delivery error response\npeer.onResponse((response) => {\n  if (response.error === ServerErrorMessages.noConsumerRegistered) {\n    // queue and retry after the consumer reconnects/registers\n    pendingEvents.push(originalEvent)\n  }\n})","preventionTips":["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"],"tags":["server-runtime","event-routing","pub-sub","consumer"],"backgroundTag":"no-subscriber-for-event","analyzedSha":"677329427f32468c74b17f3ec47eeca4e05bec65","analyzedAt":"2026-08-18T17:29:58.153Z","contentChangedAt":"2026-08-18T17:29:58.153Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}