unicity-aos/aos-ce · warning

hook-bridge: dropping response with mismatched route or…

Error message

hook-bridge: dropping response with mismatched route or principal on {reply_topic}

What it means

While fanning out hook responses, collect_responses validates each polled message against the expected reply topic and the original caller's verified principal. A message addressed to a different topic or emitted under a different principal is rejected: batch.complete is set to false and this warning is logged, and the message is skipped (continue). This guards against cross-talk between concurrent hook dispatches and spoofed responses.

Solutions

  1. Make reply_topic unique per dispatch (include a dispatch/request id) so responses can't cross routes.
  2. Ensure every responder echoes the exact reply_topic it received and replies under its own verified principal that matches the expected one.
  3. Since batch.complete is false, retry the dispatch or report incomplete results rather than treating partial responses as authoritative.
  4. Audit responder configurations to eliminate stale reply topics from previous dispatches.

Example fix

// before
let reply_topic = "oracle-replies"; // shared across dispatches
// after
let reply_topic = format!("oracle-replies/{}", dispatch_id);
Defensive patterns

Strategy: validation

Validate before calling

// Filter replies before processing
for message in poll.messages {
    if message.topic != reply_topic || message.principal.verified() != principal {
        continue; // mismatched route or principal — reject
    }
}
// Better: make the route unique up front
let reply_topic = format!("hook-replies/{}", dispatch_id);

Try / catch

// Treat partial batches as incomplete and retry or surface partials
match dispatch_hook(hook) {
    Ok(batch) if batch.complete => use(batch),
    Ok(batch) => handle_partial(batch),
    Err(e) => report(e),
}

Prevention

When it happens

Trigger: Raised in collect_responses (called from dispatch_hook) when a polled message's topic != reply_topic, or message.principal.verified() != the principal captured at dispatch time — the reply came on the wrong route or from an unauthenticated/mismatched sender.

Common situations: Multiple concurrent hook dispatches sharing a reply topic namespace with a collision; a responder replying to a stale or wrong reply_topic from a previous dispatch; a compromised or misconfigured responder sending replies under a different principal; reusing subscription handlers across dispatches without re-filtering.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of unicity-aos/aos-ce@f6f22024fb (2026-09-13). Data as JSON: /api/errors/6ec3f363ee1d2666. Report an issue: GitHub.

Appendix: source

Thrown at capsules/capsule-hook-bridge/src/lib.rs:205

        }
        let remaining = if batch.values.is_empty() {
            HOOK_COLLECT_DEADLINE_MS - elapsed_ms
        } else {
            HOOK_QUIESCENCE_MS.min(HOOK_COLLECT_DEADLINE_MS - elapsed_ms)
        };
        match subscription.recv(remaining) {
            Ok(poll) if poll.messages.is_empty() => break,
            Ok(poll) => {
                if poll.dropped != 0 || poll.lagged != 0 {
                    batch.complete = false;
                    log::warn(format!(
                        "hook-bridge: response fan-out on {reply_topic} lost messages"
                    ));
                }
                for message in poll.messages {
                    if message.topic != reply_topic || message.principal.verified() != principal {
                        batch.complete = false;
                        log::warn(format!(
                            "hook-bridge: dropping response with mismatched route or principal on {reply_topic}"
                        ));
                        continue;
                    }
                    if message.payload.len() > MAX_HOOK_RESPONSE_BYTES {
                        batch.complete = false;
                        log::warn(format!(
                            "hook-bridge: dropping oversized reply on {reply_topic}"
                        ));
                        continue;
                    }
                    match serde_json::from_str(&message.payload) {
                        Ok(value) => batch.values.push(value),
                        Err(error) => {
                            batch.complete = false;
                            log::warn(format!(
                                "hook-bridge: dropping malformed reply on {reply_topic}: {error}"
                            ));

View on GitHub (pinned to f6f22024fb)