{"record":{"id":"ec506f6fa0896b53","repo":"atuinsh/atuin","slug":"daemon-sent-a-lag-notice-as-a-history-event","errorCode":null,"errorMessage":"daemon sent a lag notice as a history event","messagePattern":"daemon sent a lag notice as a history event","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/atuin/src/command/client/history.rs","lineNumber":700,"sourceCode":"    #[serde(skip_serializing_if = \"Option::is_none\")]\n    duration_ns: Option<i64>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    duration: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    success: Option<bool>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    finished_at: Option<String>,\n}\n\n#[cfg(feature = \"daemon\")]\nimpl TailEvent {\n    fn from_proto(reply: TailHistoryReply) -> Result<Self> {\n        let (kind, history) = match reply.event {\n            Some(TailEventProto::Started(history)) => (TailKind::Started, history),\n            Some(TailEventProto::Ended(history)) => (TailKind::Ended, history),\n            Some(TailEventProto::Cancelled(history)) => (TailKind::Cancelled, history),\n            Some(TailEventProto::Lagged(_)) => {\n                bail!(\"daemon sent a lag notice as a history event\")\n            }\n            None => bail!(\"daemon sent an unspecified history tail event\"),\n        };\n        let timestamp = OffsetDateTime::from_unix_nanos_i64(history.timestamp);\n        let author_kind = history.author_kind();\n\n        Ok(Self {\n            kind,\n            history: History {\n                id: history\n                    .id\n                    .ok_or_else(|| eyre::eyre!(\"daemon tail event is missing the history id\"))?\n                    .try_into()?,\n                timestamp,\n                duration: history.duration,\n                exit: history.exit,\n                command: history.command,\n                cwd: history.cwd,","sourceCodeStart":682,"sourceCodeEnd":718,"githubUrl":"https://github.com/atuinsh/atuin/blob/900007c48045867e7f44b0f9bc55ad9dbe99ee0d/crates/atuin/src/command/client/history.rs#L682-L718","documentation":"`TailHistoryReply::from_proto` converts daemon tail-stream events into client-side events, but only Started/Ended/Cancelled carry history payloads. A `Lagged` event arriving where a history event was expected is a protocol violation by the daemon, so the client errors out.","triggerScenarios":"`atuin history tail` (or the tail streaming API) when the daemon sends a `Lagged` variant inside an event slot that from_proto expects to be a history event.","commonSituations":"Daemon/client version skew where lag signaling changed; a daemon bug or misrouted gRPC event; missed back-pressure causing lag notices to be misdelivered.","solutions":["Restart the daemon so client and daemon use matching versions/protocol.","Update the atuin binary (and daemon) to the same version.","Handle the Lagged event in the tail loop instead of treating every event as a history event (report upstream if reproducible)."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":"fn is_history_event(reply: &TailHistoryReply) -> bool {\n    matches!(\n        reply.event,\n        Some(TailEventProto::Started(_))\n            | Some(TailEventProto::Ended(_))\n            | Some(TailEventProto::Cancelled(_))\n    )\n}","tryCatchPattern":"match TailHistoryReply::from_proto(reply) {\n    Ok(ev) => handle(ev),\n    Err(e) if e.to_string().contains(\"lag notice\") => handle_lag(),\n    Err(e) => return Err(e),\n}","preventionTips":["Run daemon and client from the same atuin version.","Treat Lagged as its own stream signal, not a history event.","Report persistent protocol violations upstream."],"tags":["daemon","grpc","protocol","history-tail"],"backgroundTag":"unexpected-response-shape","analyzedSha":"900007c48045867e7f44b0f9bc55ad9dbe99ee0d","analyzedAt":"2026-09-19T12:52:51.491Z","contentChangedAt":"2026-09-19T12:52:51.491Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}