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
- Compare the fixture JSON in the test against the route's actual response and re-align parse_session_field
- Restore the session field key/shape expected by the parser
- Fix serde types in the session summary struct to match the fixture
- 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
- Keep the session field key and inner field names stable in route responses
- Encode absent sessions consistently (omitted vs null) and test both
- Update parser and fixtures together on envelope changes
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
- reply deserializes
- frozen search shape deserializes
- tool_describe payload is not valid JSON or has an unexpected
- release has no tag_name
- invalid layout migration record {}: {error}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/d0b7a4641ff6a6da.
Report an issue: GitHub.