unicity-aos/aos-ce · warning

aos-mcp: malformed host-hook bridge response

Error message

aos-mcp: malformed host-hook bridge response: {error}

What it means

relay_response deserializes the host-hook bridge response payload into HostHookResponse. On serde failure it rejects with `malformed_response` (host/event "unknown"), logs a warning with the serde error, and returns Ok(()) — the response is dropped rather than relayed to a mismatched structure.

Solutions

  1. Fix the bridge's response payload to match HostHookResponse (host, event, principal_id, etc.).
  2. Check version alignment between the host bridge and the MCP capsule's response schema.
  3. Log/inspect the raw payload on the bridge side to spot truncation or encoding problems.

Example fix

// before (bridge)
respond(json!({ "host": host }))
// after
respond(json!({ "host": host, "event": event, "principal_id": principal_id }))
Defensive patterns

Strategy: try-catch

Validate before calling

// Bridge side: verify response shape before delivering
if resp.get("principal_id").is_none() {
    return Err("host-hook response missing principal_id");
}

Type guard

fn is_valid_hook_response(v: &serde_json::Value) -> bool {
    v.get("host").and_then(|h| h.as_str()).is_some()
        && v.get("principal_id").and_then(|p| p.as_str()).is_some()
}

Try / catch

match serde_json::from_value::<HostHookResponse>(payload) {
    Ok(resp) => relay(resp),
    Err(e) => { reject("unknown", "unknown", "malformed_response"); log::warn!("malformed response: {e}"); }
}

Prevention

When it happens

Trigger: relay_response(payload) receives JSON that doesn't match HostHookResponse: missing principal_id, wrong event/host types, or non-JSON bytes.

Common situations: Host bridge emitting a response schema from an older/newer version, truncation or corruption of the payload in transit, or a bridge bug serializing optional fields incorrectly.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at capsules/capsule-mcp/src/host_hooks.rs:124

            host: &request.host,
            session_id: &request.session_id,
            event: &request.event,
            correlation_id: &request.correlation_id,
            route_id: &request.route_id,
            delivery_id: &request.delivery_id,
            turn_id: request.turn_id.as_deref(),
            workspace_id: request.workspace_id.as_deref(),
            payload: &request.payload,
        },
    )
}

pub(crate) fn relay_response(payload: serde_json::Value) -> Result<(), SysError> {
    let response: HostHookResponse = match serde_json::from_value(payload) {
        Ok(response) => response,
        Err(error) => {
            reject("unknown", "unknown", "malformed_response");
            log::warn(format!(
                "aos-mcp: malformed host-hook bridge response: {error}"
            ));
            return Ok(());
        }
    };
    let event = response.event.as_deref().unwrap_or("unknown");
    if let Err(reason) = validate_response_shape(&response) {
        reject(&response.host, event, reason);
        return Ok(());
    }

    let caller = match runtime::caller() {
        Ok(caller) => caller,
        Err(error) => {
            reject(&response.host, event, "caller_unavailable");
            log::warn(format!(
                "aos-mcp: caller unavailable for host-hook response: {error}"
            ));

View on GitHub (pinned to f6f22024fb)