{"record":{"id":"d0b7a4641ff6a6da","repo":"astrid-runtime/astrid","slug":"present-session","errorCode":null,"errorMessage":"present session","messagePattern":"present session","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-gateway/src/routes/sessions_tests.rs","lineNumber":632,"sourceCode":"    // Absent `session` → None too.\n    let absent = serde_json::json!({ \"correlation_id\": \"c\" });\n    assert!(parse_session_field(&absent).unwrap().is_none());\n}\n\n#[test]\nfn parse_session_field_present_summary_deserializes() {\n    let reply = serde_json::json!({\n        \"correlation_id\": \"c\",\n        \"session\": {\n            \"session_id\": \"s1\",\n            \"title\": \"T\",\n            \"message_count\": 3,\n            \"archived\": false\n        }\n    });\n    let s = parse_session_field(&reply)\n        .unwrap()\n        .expect(\"present session\");\n    assert_eq!(s.session_id, \"s1\");\n    assert_eq!(s.title.as_deref(), Some(\"T\"));\n    assert_eq!(s.message_count, 3);\n}\n\n#[test]\nfn parse_session_field_rejects_garbage_session() {\n    // `session` present but not an object the SUMMARY agrees to → Kernel.\n    let reply = serde_json::json!({ \"session\": { \"session_id\": 42 } });\n    assert!(matches!(\n        parse_session_field(&reply).unwrap_err(),\n        GatewayError::Kernel(_)\n    ));\n}\n\n#[test]\nfn parse_deleted_field_reads_bool_defaults_false() {\n    assert!(parse_deleted_field(&serde_json::json!({ \"deleted\": true })));","sourceCodeStart":614,"sourceCodeEnd":650,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-gateway/src/routes/sessions_tests.rs#L614-L650","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n{\"session\": {\"id\": \"s1\", ...}}\n// after\n{\"session\": {\"session_id\": \"s1\", ...}} // match parser's expected field names","handlingStrategy":"validation","validationCode":"assert!(reply.get(\"session\").map_or(false, |s| s.get(\"session_id\").is_some()),\n    \"reply must carry a present session with session_id\");","typeGuard":"fn has_present_session(reply: &serde_json::Value) -> bool {\n    reply.get(\"session\")\n        .map_or(false, |s| s.get(\"session_id\").map_or(false, |v| v.is_string()))\n}","tryCatchPattern":"let s = parse_session_field(&reply)\n    .expect(\"session field parses\")\n    .unwrap_or_else(|| panic!(\"present session; reply={reply}\"));","preventionTips":["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"],"tags":["tests","json","deserialization","parser"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}