{"record":{"id":"6b839b384cb503d3","repo":"unicity-aos/aos-ce","slug":"failed-to-deserialize-compaction-response-payload-e","errorCode":null,"errorMessage":"failed to deserialize compaction response payload: {e}","messagePattern":"failed to deserialize compaction response payload: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"capsules/capsule-context-engine/src/lib.rs","lineNumber":591,"sourceCode":"    if !responses.is_empty() {\n        log::info(format!(\n            \"Collected {} context_engine.v1.hook.before_compaction responses\",\n            responses.len()\n        ));\n    }\n\n    merge_before_compaction_responses(&responses)\n}\n\n/// Parse hook responses from a typed `PollResult`.\nfn parse_hook_responses(result: &ipc::PollResult) -> Vec<BeforeCompactionHookResponse> {\n    let mut responses = Vec::new();\n\n    for msg in &result.messages {\n        let payload: serde_json::Value = match serde_json::from_str(&msg.payload) {\n            Ok(v) => v,\n            Err(e) => {\n                log::warn(format!(\n                    \"failed to deserialize compaction response payload: {e}\"\n                ));\n                continue;\n            }\n        };\n\n        // Try direct payload, then nested in Custom `data` envelope.\n        let maybe_response =\n            serde_json::from_value::<BeforeCompactionHookResponse>(payload.clone())\n                .ok()\n                .filter(BeforeCompactionHookResponse::has_any_field)\n                .or_else(|| {\n                    payload\n                        .get(\"data\")\n                        .and_then(|data| {\n                            serde_json::from_value::<BeforeCompactionHookResponse>(data.clone())\n                                .ok()\n                        })","sourceCodeStart":573,"sourceCodeEnd":609,"githubUrl":"https://github.com/unicity-aos/aos-ce/blob/f6f22024fb1e8d122f28a1b4a9f75aee448ae839/capsules/capsule-context-engine/src/lib.rs#L573-L609","documentation":"parse_hook_responses reads compaction hook reply messages and deserializes each payload as JSON. A payload that fails serde_json::from_str triggers this warning and the message is skipped; valid responses are still collected. It exists so one malformed hook reply cannot abort parsing of the whole compaction response batch.","triggerScenarios":"fire_before_compaction (or parsing from a poll result) receives hook replies where msg.payload is not valid JSON — a hook capsule crashed mid-write, published an empty string, or emitted a non-JSON error blob.","commonSituations":"A hook adapter returning raw error text instead of a JSON envelope; concurrent writers interleaving on a channel; hook implementations in other languages with buggy serializers; unit tests parse_hook_responses_nested_in_custom_data / mixed_valid_and_invalid deliberately feed bad payloads.","solutions":["Fix the offending hook to publish replies through serde_json (or the language's JSON serializer) with the documented response envelope.","Log the reply topic and sender principal with the parse error to locate the faulty hook.","Add a producer-side test that round-trips the compaction response through serde_json before publishing.","If partial responses are expected, decide policy: retry failed hooks or proceed with the parsed subset."],"exampleFix":"// before: hook publishes a bare string error\nbus.publish(reply_topic, format!(\"hook failed: {err}\"));\n// after: hook publishes a JSON envelope\nlet reply = serde_json::json!({ \"ok\": false, \"error\": err.to_string() });\nbus.publish(reply_topic, serde_json::to_string(&reply)?);","handlingStrategy":"type-guard","validationCode":"// pre-validate hook reply before publishing\nserde_json::to_string(&reply).expect(\"hook reply must be JSON\");","typeGuard":"fn parse_reply(payload: &str) -> Option<serde_json::Value> {\n    serde_json::from_str(payload).ok()\n}","tryCatchPattern":null,"preventionTips":["Publish hook replies via serde_json only","Include a round-trip serialization test per hook","Log reply topic + sender on parse failure to find the bad hook fast"],"tags":["ipc","json","deserialization","hooks","rust"],"backgroundTag":"json-parse-error","analyzedSha":"f6f22024fb1e8d122f28a1b4a9f75aee448ae839","analyzedAt":"2026-09-13T03:04:44.565Z","contentChangedAt":"2026-09-13T03:04:44.565Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}