{"record":{"id":"2ca44301575808b1","repo":"astrid-runtime/astrid","slug":"request-arrives","errorCode":null,"errorMessage":"request arrives","messagePattern":"request arrives","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-gateway/src/routes/sessions_tests.rs","lineNumber":729,"sourceCode":"    ));\n}\n\n/// Live round-trip over a real `EventBus` for the `update` verb: the\n/// stand-in capsule receives the principal-stamped, present-keys-only\n/// patch and replies with an updated SUMMARY on the scoped topic.\n#[tokio::test]\nasync fn request_capsule_round_trips_update_reply() {\n    let bus = Arc::new(EventBus::new());\n    let principal = PrincipalId::new(\"alice\").expect(\"valid principal\");\n    let correlation_id = \"corr-upd-1\";\n    let response_topic = format!(\"{TOPIC_UPDATE_RESPONSE_PREFIX}.{correlation_id}\");\n\n    let mut req_rx = bus.subscribe_topic(TOPIC_UPDATE_REQUEST.to_string());\n    let bus_capsule = Arc::clone(&bus);\n    let resp_topic = response_topic.clone();\n    let cid = correlation_id.to_string();\n    let capsule = tokio::spawn(async move {\n        let event = req_rx.recv().await.expect(\"request arrives\");\n        let AstridEvent::Ipc { message, .. } = &*event else {\n            panic!(\"expected IPC request\");\n        };\n        // Principal-stamped, and the patch carries only the sent key.\n        assert_eq!(message.principal.as_deref(), Some(\"alice\"));\n        assert_ne!(message.source_id, Uuid::nil());\n        assert_eq!(message.origin, MessageOrigin::RemoteGateway);\n        if let IpcPayload::RawJson(v) = &message.payload {\n            assert_eq!(v[\"title\"], \"renamed\");\n            assert!(v.get(\"archived\").is_none(), \"absent key not forwarded\");\n        } else {\n            panic!(\"expected RawJson payload\");\n        }\n        let reply = serde_json::json!({\n            \"correlation_id\": cid,\n            \"session\": {\n                \"session_id\": \"sess-1\",\n                \"title\": \"renamed\",","sourceCodeStart":711,"sourceCodeEnd":747,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-gateway/src/routes/sessions_tests.rs#L711-L747","documentation":"This panic comes from `req_rx.recv().await.expect(\"request arrives\")` inside the stand-in capsule task in `request_capsule_round_trips_update_reply`. It fires when the subscribed EventBus topic stream ends (recv returns None) before any `update` request event is delivered, i.e. the subscription closed without a message.","triggerScenarios":"The helper under test (`update_session` path) never publishes an `AstridEvent::Ipc` on `TOPIC_UPDATE_REQUEST` before the capsule task's receiver channel closes — e.g. the helper errored out early, published on a different topic name, or the EventBus dropped its publisher side.","commonSituations":"Topic constant renamed so producer and consumer disagree; the helper returns Err before publishing (surface it via the other expect at line ~780); async task raced and the bus was dropped; EventBus subscription API changed semantics so recv now ends on idle.","solutions":["Confirm the helper publishes to exactly `TOPIC_UPDATE_REQUEST` for the update verb.","Check whether the update helper returned Err and surface that error first; a helper failure usually starves this receiver.","Keep the publisher (bus Arc) alive for the duration of the test so the channel cannot close early.","Replace expect with explicit matching on None vs Some to distinguish channel-closed from timeout."],"exampleFix":"// before\nlet event = req_rx.recv().await.expect(\"request arrives\");\n// after\nlet Some(event) = req_rx.recv().await else {\n    panic!(\"update request channel closed before a request arrived\");\n};","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match req_rx.recv().await {\n    Some(event) => { /* handle */ }\n    None => panic!(\"request channel closed before delivery\"),\n}","preventionTips":["Keep the publisher Arc alive for the whole test","Assert topic constants are shared between producer and consumer","Surface helper errors before awaiting the receiving task"],"tags":["rust","tokio","test","panic","event-bus"],"backgroundTag":"channel-closed","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}