{"record":{"id":"cfba611f1b88e3bb","repo":"zellij-org/zellij","slug":"layoutinfo-missing-layout-type","errorCode":null,"errorMessage":"LayoutInfo missing layout_type","messagePattern":"LayoutInfo missing layout_type","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"zellij-utils/src/ipc/protobuf_conversion.rs","lineNumber":3264,"sourceCode":"    fn try_from(\n        layout: crate::client_server_contract::client_server_contract::LayoutInfo,\n    ) -> Result<Self> {\n        use crate::client_server_contract::client_server_contract::layout_info::LayoutType;\n        match layout.layout_type {\n            Some(LayoutType::BuiltinName(name)) => Ok(crate::data::LayoutInfo::BuiltIn(name)),\n            Some(LayoutType::FilePath(path)) => {\n                let layout_metadata = layout\n                    .layout_metadata\n                    .map(|m| m.try_into())\n                    .transpose()?\n                    .unwrap_or_default();\n                Ok(crate::data::LayoutInfo::File(path, layout_metadata))\n            },\n            Some(LayoutType::Url(url)) => Ok(crate::data::LayoutInfo::Url(url)),\n            Some(LayoutType::Stringified(content)) => {\n                Ok(crate::data::LayoutInfo::Stringified(content))\n            },\n            None => Err(anyhow!(\"LayoutInfo missing layout_type\")),\n        }\n    }\n}\n\nimpl From<crate::data::LayoutMetadata> for ProtoLayoutMetadata {\n    fn from(metadata: crate::data::LayoutMetadata) -> Self {\n        ProtoLayoutMetadata {\n            tabs: metadata.tabs.into_iter().map(|t| t.into()).collect(),\n            creation_time: metadata.creation_time,\n            update_time: metadata.update_time,\n        }\n    }\n}\n\nimpl TryFrom<ProtoLayoutMetadata> for crate::data::LayoutMetadata {\n    type Error = anyhow::Error;\n    fn try_from(proto_metadata: ProtoLayoutMetadata) -> Result<Self> {\n        let tabs = proto_metadata","sourceCodeStart":3246,"sourceCodeEnd":3282,"githubUrl":"https://github.com/zellij-org/zellij/blob/98a0837077492d53dd252ab30bc3e43e41e504f4/zellij-utils/src/ipc/protobuf_conversion.rs#L3246-L3282","documentation":"LayoutInfo describes where a layout comes from; its protobuf representation is a oneof layout_type with variants FilePath, BuiltinName, Url, and Stringified, plus an optional layout_metadata. The conversion into data::LayoutInfo matches on the oneof; when layout_type is None (no oneof arm set - legal in proto3), there is no source to build a LayoutInfo from, so it fails with 'LayoutInfo missing layout_type'.","triggerScenarios":"Sending a LayoutInfo message where the oneof was never set, e.g. constructing ProtoArrayLayout/LayoutInfo via default() and filling only layout_metadata, or a client that serializes a layout struct without the source field.","commonSituations":"Plugins or session-management tooling sending resurrect/layout payloads over IPC; version skew where the sender's LayoutInfo lacks the oneof field; code that copies layout_metadata between messages and drops layout_type.","solutions":["Set exactly one oneof arm before sending: layout_type: Some(FilePath(path)), BuiltinName(name), Url(url), or Stringified(content).","If you built the message with default(), remember optional oneof fields do not default - assign them explicitly.","Check the receiver supports the variant you send (the converter handles FilePath, Url, and Stringified; verify BuiltinName support on your version).","Rebuild senders against the same zellij contract version as the server."],"exampleFix":"// before\nlet layout_info = LayoutInfo {\n    layout_metadata: Some(metadata),\n    layout_type: None, // -> \"LayoutInfo missing layout_type\"\n};\n\n// after\nlet layout_info = LayoutInfo {\n    layout_metadata: Some(metadata),\n    layout_type: Some(layout_info::LayoutType::Stringified(\n        \"layout { pane direction=\"1\" }\".to_string(),\n    )),\n};","handlingStrategy":"validation","validationCode":"fn layout_info_is_convertible(li: &LayoutInfo) -> bool {\n    li.layout_type.is_some()\n}","typeGuard":"fn has_layout_source(li: &LayoutInfo) -> bool {\n    matches!(\n        li.layout_type,\n        Some(layout_info::LayoutType::FilePath(_))\n            | Some(layout_info::LayoutType::BuiltinName(_))\n            | Some(layout_info::LayoutType::Url(_))\n            | Some(layout_info::LayoutType::Stringified(_))\n    )\n}","tryCatchPattern":"match zellij_utils::data::LayoutInfo::try_from(proto_layout_info) {\n    Ok(info) => use_layout(info),\n    Err(e) if e.to_string().contains(\"LayoutInfo missing layout_type\") => {\n        log::warn!(\"LayoutInfo without a source oneof arm - ignoring\");\n    },\n    Err(e) => return Err(e),\n}","preventionTips":["Remember proto3 oneof arms have no default - unset means None and fails here.","When copying LayoutInfo between messages, copy layout_type and layout_metadata together.","Set exactly one source arm (FilePath / BuiltinName / Url / Stringified) and verify the receiver supports it on your zellij version."],"tags":["zellij","ipc","protobuf","rust","layout","oneof"],"backgroundTag":null,"analyzedSha":"98a0837077492d53dd252ab30bc3e43e41e504f4","analyzedAt":"2026-08-16T13:02:01.396Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}