{"record":{"id":"a6f96e0944ed05d4","repo":"EpicGames/lore","slug":"response-parse-should-work","errorCode":null,"errorMessage":"response parse should work","messagePattern":"response parse should work","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lore-server/src/quic/replication_store_service/server.rs","lineNumber":1129,"sourceCode":"\n        // ImmutableLocalQuery should find the data via the local store\n        let parse_output = service\n            .parse_request_bytes(\n                &CommandHeader::new(Command::ImmutableLocalQuery as QuicOpCode, 0, 0),\n                collapse_bytes_without_header(&request.clone().to_quic_chunks()),\n            )\n            .expect(\"Failed to parse\");\n        assert!(matches!(\n            parse_output,\n            ParsedReplicationStoreRequest::Query(_)\n        ));\n\n        let handle_output = service\n            .run_request_handler(AttributeMap::default().into(), parse_output)\n            .await\n            .expect(\"handler failed\");\n        let response = QueryResponse::parse(collapse_bytes(&handle_output))\n            .expect(\"response parse should work\");\n        assert_eq!(response.results[0].match_made, StoreMatch::MatchFull);\n\n        // ImmutableQuery should NOT find it (main store is empty)\n        let parse_output = service\n            .parse_request_bytes(\n                &CommandHeader::new(Command::ImmutableQuery as QuicOpCode, 0, 0),\n                collapse_bytes_without_header(&request.to_quic_chunks()),\n            )\n            .expect(\"Failed to parse\");\n\n        let handle_output = service\n            .run_request_handler(AttributeMap::default().into(), parse_output)\n            .await\n            .expect(\"handler failed\");\n        let response = QueryResponse::parse(collapse_bytes(&handle_output))\n            .expect(\"response parse should work\");\n        assert_eq!(response.results[0].match_made, StoreMatch::MatchNone);\n    }","sourceCodeStart":1111,"sourceCodeEnd":1147,"githubUrl":"https://github.com/EpicGames/lore/blob/074eb0b0d1194c997d7cf28b55519e3e197b3e23/lore-server/src/quic/replication_store_service/server.rs#L1111-L1147","documentation":"A panic from `.expect(\"response parse should work\")` on `QueryResponse::parse(collapse_bytes(&handle_output))` in `immutable_local_query_routes_to_local_store`. The handler completed but the returned bytes are not a valid QueryResponse — likely an empty body, an error-encoded response, or a serialization change in QueryResponse. The library throws this when the response bytes do not conform to the expected QueryResponse wire format.","triggerScenarios":"run_request_handler returned bytes that QueryResponse::parse rejects: an empty Vec (e.g. a ClientIdentify-style early return), an error frame instead of a query result, or a QueryResponse serialized with a different op/version than the parser expects.","commonSituations":"Changing QueryResponse's serialization (field order, count prefix) without updating parse; the handler returned an empty result because the query matched nothing (store routing wrong); collapsing multi-chunk responses incorrectly in the test helper `collapse_bytes`.","solutions":["Print `collapse_bytes(&handle_output)` (length + hex) before parsing to see what the handler actually produced.","Check that the handler returned a QueryResponse and not an empty/error body (an early `return Ok(vec![])` path yields unparseable bytes).","Verify QueryResponse::parse and its serialization counterpart are in sync after any format change.","Ensure `collapse_bytes` concatenates all chunks including the header the parser expects."],"exampleFix":"// before\nlet response = QueryResponse::parse(collapse_bytes(&handle_output))\n    .expect(\"response parse should work\");\n// after\nlet raw = collapse_bytes(&handle_output);\nlet response = QueryResponse::parse(raw.clone())\n    .unwrap_or_else(|e| panic!(\"response parse failed ({} bytes): {e:?}\", raw.len()));","handlingStrategy":"validation","validationCode":"let raw = collapse_bytes(&handle_output);\nassert!(!raw.is_empty(), \"handler returned empty body\");\n// optionally check a leading marker/version byte if QueryResponse has one","typeGuard":"fn is_parsable_query_response(raw: &[u8]) -> bool {\n    QueryResponse::parse(raw.to_vec()).is_ok()\n}","tryCatchPattern":"let response = QueryResponse::parse(raw).unwrap_or_else(|e| {\n    panic!(\"QueryResponse parse failed ({:?}): {e:?}\", &raw[..raw.len().min(32)])\n});","preventionTips":["Add round-trip tests (serialize -> parse) for QueryResponse on every format change.","Assert handler output non-empty before parsing.","Keep chunk-collapse helpers covered by their own unit tests."],"tags":["rust","test-panic","deserialization","query-response"],"backgroundTag":"unexpected-response-shape","analyzedSha":"074eb0b0d1194c997d7cf28b55519e3e197b3e23","analyzedAt":"2026-09-13T09:00:57.509Z","contentChangedAt":"2026-09-13T09:00:57.509Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}