astrid-runtime/astrid · error

alice

Error message

alice

What it means

This panic comes from `PrincipalId::new("alice").expect("valid principal")` in `request_capsule_round_trips_update_reply`. `PrincipalId::new` validates its input and returns a Result; the expect fires when the principal string fails validation, so no valid PrincipalId could be constructed for the test run.

Source

Thrown at crates/astrid-gateway/src/routes/sessions_tests.rs:720

    assert!(parse_search_response(body).unwrap().next_cursor.is_none());
}

#[test]
fn parse_search_response_rejects_garbage() {
    let body = serde_json::json!({ "results": "not-an-array" });
    assert!(matches!(
        parse_search_response(body).unwrap_err(),
        GatewayError::Kernel(_)
    ));
}

/// Live round-trip over a real `EventBus` for the `update` verb: the
/// stand-in capsule receives the principal-stamped, present-keys-only
/// patch and replies with an updated SUMMARY on the scoped topic.
#[tokio::test]
async fn request_capsule_round_trips_update_reply() {
    let bus = Arc::new(EventBus::new());
    let principal = PrincipalId::new("alice").expect("valid principal");
    let correlation_id = "corr-upd-1";
    let response_topic = format!("{TOPIC_UPDATE_RESPONSE_PREFIX}.{correlation_id}");

    let mut req_rx = bus.subscribe_topic(TOPIC_UPDATE_REQUEST.to_string());
    let bus_capsule = Arc::clone(&bus);
    let resp_topic = response_topic.clone();
    let cid = correlation_id.to_string();
    let capsule = tokio::spawn(async move {
        let event = req_rx.recv().await.expect("request arrives");
        let AstridEvent::Ipc { message, .. } = &*event else {
            panic!("expected IPC request");
        };
        // Principal-stamped, and the patch carries only the sent key.
        assert_eq!(message.principal.as_deref(), Some("alice"));
        assert_ne!(message.source_id, Uuid::nil());
        assert_eq!(message.origin, MessageOrigin::RemoteGateway);
        if let IpcPayload::RawJson(v) = &message.payload {
            assert_eq!(v["title"], "renamed");

View on GitHub (pinned to affd8760f4)

Solutions

  1. Print or log the error from PrincipalId::new instead of expect() to see the exact validation rule that rejected "alice".
  2. Update the fixture principal to a value that satisfies the current PrincipalId validation rules.
  3. If "alice" should remain valid, relax or fix the validation in PrincipalId::new.
  4. Replace expect with a test-level assert that surfaces the underlying error message.

Example fix

// before
let principal = PrincipalId::new("alice").expect("valid principal");
// after
let principal = PrincipalId::new("alice")
    .unwrap_or_else(|e| panic!("valid principal: {e:?}"));
Defensive patterns

Strategy: validation

Validate before calling

if name.is_empty() || name.len() > 64 || !name.chars().all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_') {
    return Err("invalid principal id");
}

Type guard

fn valid_principal(s: &str) -> Option<PrincipalId> {
    PrincipalId::new(s).ok()
}

Try / catch

let principal = PrincipalId::new("alice")
    .unwrap_or_else(|e| panic!("valid principal: {e:?}"));

Prevention

When it happens

Trigger: Calling `PrincipalId::new` with a string that violates the identifier rules (empty, too long, or containing characters outside the allowed set). In this test that means the hard-coded `"alice"` was rejected, which only happens if the validation rules were tightened or the constructor signature/behavior changed.

Common situations: A validation change made short lowercase names invalid; the constructor was refactored to require a prefixed/UUID form; copy-pasted principal constants contain whitespace or non-ASCII characters.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/84490a47c85c8755. Report an issue: GitHub.