astrid-runtime/astrid · error

present session

Error message

present session

What it means

parse_session_field_present_summary_deserializes builds a reply containing a present session object and calls parse_session_field, expecting Some(session). The expect("present session") panics if the parser returns Ok(None) — the reply's shape did not register as containing a session — or via a prior unwrap if parsing failed outright.

Source

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

    // Absent `session` → None too.
    let absent = serde_json::json!({ "correlation_id": "c" });
    assert!(parse_session_field(&absent).unwrap().is_none());
}

#[test]
fn parse_session_field_present_summary_deserializes() {
    let reply = serde_json::json!({
        "correlation_id": "c",
        "session": {
            "session_id": "s1",
            "title": "T",
            "message_count": 3,
            "archived": false
        }
    });
    let s = parse_session_field(&reply)
        .unwrap()
        .expect("present session");
    assert_eq!(s.session_id, "s1");
    assert_eq!(s.title.as_deref(), Some("T"));
    assert_eq!(s.message_count, 3);
}

#[test]
fn parse_session_field_rejects_garbage_session() {
    // `session` present but not an object the SUMMARY agrees to → Kernel.
    let reply = serde_json::json!({ "session": { "session_id": 42 } });
    assert!(matches!(
        parse_session_field(&reply).unwrap_err(),
        GatewayError::Kernel(_)
    ));
}

#[test]
fn parse_deleted_field_reads_bool_defaults_false() {
    assert!(parse_deleted_field(&serde_json::json!({ "deleted": true })));

View on GitHub (pinned to affd8760f4)

Solutions

  1. Compare the fixture JSON in the test against the route's actual response and re-align parse_session_field
  2. Restore the session field key/shape expected by the parser
  3. Fix serde types in the session summary struct to match the fixture
  4. Ensure the parser's None case (absent session) still triggers only on genuinely absent sessions

Example fix

// before
{"session": {"id": "s1", ...}}
// after
{"session": {"session_id": "s1", ...}} // match parser's expected field names
Defensive patterns

Strategy: validation

Validate before calling

assert!(reply.get("session").map_or(false, |s| s.get("session_id").is_some()),
    "reply must carry a present session with session_id");

Type guard

fn has_present_session(reply: &serde_json::Value) -> bool {
    reply.get("session")
        .map_or(false, |s| s.get("session_id").map_or(false, |v| v.is_string()))
}

Try / catch

let s = parse_session_field(&reply)
    .expect("session field parses")
    .unwrap_or_else(|| panic!("present session; reply={reply}"));

Prevention

When it happens

Trigger: Changing the sessions reply envelope so the session field key, nesting, or field names no longer match what parse_session_field recognizes; the session object failing to deserialize into the expected summary struct.

Common situations: Renaming the session field in the route response; changing how absent vs present sessions are encoded (null vs omitted vs object); field type drift (message_count string vs number) in the handler.

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 astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/d0b7a4641ff6a6da. Report an issue: GitHub.