zeroclaw-labs/zeroclaw · critical · anyhow::Error

amqp.{}: dispatch = {:?} routes to the SOP engine but no SOP

Error message

amqp.{}: dispatch = {:?} routes to the SOP engine but no SOP engine/audit handles are available; refusing to start a channel that would acknowledge deliveries without dispatching them

What it means

AmqpChannel::new refuses to construct when dispatch is Sop or SopAndAgentLoop but the SOP engine and/or audit logger handles are absent. Without them the consumer loop would acknowledge broker deliveries that were never dispatched anywhere — silent message loss — so the constructor fails closed at startup instead.

Source

Thrown at crates/zeroclaw-channels/src/amqp.rs:87

    /// in SOP-only dispatch mode. The delivery was NOT fully handled: under
    /// `durable_ack` it must be nack/requeued for redelivery rather than acked,
    /// so the trigger is retried once capacity frees instead of being lost. Never
    /// returned for combined `sop_and_agent_loop` dispatch - there, the agent loop
    /// already consumed the delivery, so a SOP-side overflow is surfaced loudly
    /// and acked rather than risking a broker redelivery that would double-run
    /// the agent side (see `route_delivery`).
    Deferred,
    ReceiverGone,
}

impl AmqpChannel {
    pub fn new(cfg: AmqpChannelConfig) -> anyhow::Result<Self> {
        let routes_sop = matches!(
            cfg.dispatch,
            SopDispatch::Sop | SopDispatch::SopAndAgentLoop
        );
        if routes_sop && (cfg.engine.is_none() || cfg.audit.is_none()) {
            anyhow::bail!(
                "amqp.{}: dispatch = {:?} routes to the SOP engine but no SOP \
                 engine/audit handles are available; refusing to start a \
                 channel that would acknowledge deliveries without dispatching \
                 them",
                cfg.alias,
                cfg.dispatch
            );
        }
        Ok(Self {
            amqp_url: cfg.amqp_url,
            exchange: cfg.exchange,
            routing_keys: cfg.routing_keys,
            queue: cfg.queue,
            ca_cert: cfg.ca_cert,
            client_cert: cfg.client_cert,
            client_key: cfg.client_key,
            sender_label: cfg.sender_label,
            content_template: cfg.content_template,

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Provide both handles in AmqpChannelConfig: wire the SopEngine (Arc<Mutex<SopEngine>>) and SopAuditLogger (Arc<SopAuditLogger>) through from the runtime.
  2. Or switch the channel's dispatch to agent_loop if SOP routing is not actually needed.
  3. Check the config surface that builds AmqpChannelConfig — SOP enablement is usually global, so verify the engine is on at all before setting per-channel dispatch.

Example fix

// before
let ch = AmqpChannel::new(AmqpChannelConfig {
    dispatch: SopDispatch::Sop,
    engine: None,
    audit: None,
    // ...
})?;

// after
let ch = AmqpChannel::new(AmqpChannelConfig {
    dispatch: SopDispatch::Sop,
    engine: Some(engine_handle),
    audit: Some(audit_handle),
    // ...
})?;
Defensive patterns

Strategy: validation

Validate before calling

let routes_sop = matches!(cfg.dispatch, SopDispatch::Sop | SopDispatch::SopAndAgentLoop);
if routes_sop && (cfg.engine.is_none() || cfg.audit.is_none()) {
    anyhow::bail!(
        "config error: amqp.{} needs SOP engine+audit handles or dispatch = agent_loop",
        cfg.alias
    );
}

Prevention

When it happens

Trigger: Channel configuration sets amqp dispatch to sop (or sop_and_agent_loop) while the SOP subsystem is disabled or unwired, so AmqpChannelConfig.engine and/or .audit are None when AmqpChannel::new runs.

Common situations: Enabling SOP routing in config while the SOP engine is disabled globally; refactors that stop threading engine/audit handles into channel construction; test or staging wiring that omits the handles.

Understand the failure class

Background: Config validation failed: what "invalid value for {key}" and settings-rejection errors mean across 19 open-source libraries — this error's family across 19 libraries.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/91d01cc8fa3fcfa6. Report an issue: GitHub.