astrid-runtime/astrid · error
stand-in capsule joins
Error message
stand-in capsule joins
What it means
This panic comes from `capsule.await.expect("stand-in capsule joins")` in `request_capsule_round_trips_update_reply`. Joining the spawned stand-in capsule task yielded Err (or the JoinHandle was aborted), which in tokio means the task itself panicked or was cancelled. It usually indicates the assertions inside the capsule (request shape, principal stamp) failed first.
Source
Thrown at crates/astrid-gateway/src/routes/sessions_tests.rs:782
});
let body = serde_json::json!({ "title": "renamed" });
let payload = build_update_payload(correlation_id, "sess-1", &body).unwrap();
let value = request_capsule(
&bus,
TOPIC_UPDATE_REQUEST,
&response_topic,
payload,
correlation_id,
&principal,
None,
&[test_provider_source_id()],
CAPSULE_TIMEOUT,
)
.await
.expect("helper returns the scoped reply");
capsule.await.expect("stand-in capsule joins");
let summary = parse_session_field(&value)
.unwrap()
.expect("present session");
assert_eq!(summary.session_id, "sess-1");
assert_eq!(summary.title.as_deref(), Some("renamed"));
}
/// A reply stamped for a different principal is ignored. This protects a
/// same-topic reply from satisfying another caller's request.
#[tokio::test]
async fn request_capsule_ignores_wrong_principal_reply() {
let bus = Arc::new(EventBus::new());
let principal = PrincipalId::new("alice").expect("valid principal");
let correlation_id = "corr-want-principal";
let response_topic = format!("{TOPIC_LIST_RESPONSE_PREFIX}.{correlation_id}");
let bus_bg = Arc::clone(&bus);
let resp_topic = response_topic.clone();View on GitHub (pinned to affd8760f4)
Solutions
- Run with `cargo test -- --nocapture` to see the inner capsule panic message, which names the real failing assertion.
- Fix the helper/event so the delivered AstridEvent::Ipc carries principal Some("alice"), non-nil source_id, and only the patched key.
- Replace the expect with match on the JoinError to report the inner panic explicitly.
- Ensure the test does not return/abort before joining the capsule task.
Example fix
// before
capsule.await.expect("stand-in capsule joins");
// after
if let Err(e) = capsule.await {
panic!("stand-in capsule joins: {e}");
} Defensive patterns
Strategy: try-catch
Try / catch
if let Err(e) = capsule.await {
panic!("stand-in capsule joins: {e}");
} Prevention
- Run failing tests with --nocapture to expose the inner panic
- Keep capsule assertions narrow and message-rich
- Join spawned tasks before the test future ends to avoid aborts
When it happens
Trigger: The inner capsule task panicked — e.g. its `expect("request arrives")`, the `AstridEvent::Ipc` pattern-match `panic!("expected IPC request")`, or `assert_eq!(message.principal.as_deref(), Some("alice"))` failed — so JoinHandle::await returns JoinError.
Common situations: The helper sends a differently shaped event (not AstridEvent::Ipc); patch contains extra keys so the present-keys-only assertion fails; the event's principal stamp is missing or wrong; task aborted because the test future was dropped early.
Related errors
- request arrives
- empty page deserializes
- alice
- helper returns the scoped reply
- our own event is delivered
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/3802c4137da82de5.
Report an issue: GitHub.