zellij-org/zellij · error · anyhow::Error
Failed to deserialize layout: {}
Error message
Failed to deserialize layout: {} What it means
In the switch-session host function, a stringified layout arriving from the plugin is pre-validated with Layout::from_kdl before the session switch proceeds; this error aborts the switch when that KDL fails to parse. The early check exists so the failure surfaces now instead of mid-session-switch.
Source
Thrown at zellij-server/src/plugins/zellij_exports.rs:2965
let error_msg = || format!("Failed to detach");
apply_action!(action, error_msg, env);
}
fn switch_session(
env: &PluginEnv,
session_name: Option<String>,
tab_position: Option<usize>,
pane_id: Option<(u32, bool)>,
layout: Option<LayoutInfo>,
cwd: Option<PathBuf>,
) -> Result<()> {
// pane_id is (id, is_plugin)
let err_context = || format!("Failed to switch session");
if let Some(LayoutInfo::Stringified(stringified_layout)) = layout.as_ref() {
// we verify the stringified layout here to fail early rather than when parsing it at the
// session-switching phase
if let Err(e) = Layout::from_kdl(&stringified_layout, None, None, None) {
return Err(anyhow!("Failed to deserialize layout: {}", e));
}
}
let (completion_tx, completion_rx) = oneshot::channel();
if session_name
.as_ref()
.map(|s| s.contains('/'))
.unwrap_or(false)
{
log::error!("Session names cannot contain \'/\'");
} else {
let client_id = env.client_id;
let tab_position = tab_position.map(|p| p + 1); // ¯\_()_/¯
let cwd = cwd
.map(|c| translate_plugin_path(env, c))
.or_else(|| Some(env.plugin_cwd.clone()));
let connect_to_session = ConnectToSession {View on GitHub (pinned to 98a0837077)
Solutions
- Run `zellij setup --check` on the same layout content to see the precise KDL error
- Re-serialize the layout with the current zellij version (dump it fresh via the dump-layout API) rather than reusing an old blob
- If sessions were saved by an older zellij, migrate/re-dump them before switching
- Handle the Err return in the plugin and surface the message to the user instead of retrying the switch
Defensive patterns
Strategy: validation
Validate before calling
// plugin-side: pre-validate stringified layouts before switching sessions
if let Some(LayoutInfo::Stringified(s)) = layout.as_ref() {
if kdl_parse_fails(s) { return Err(anyhow!("layout blob no longer valid; re-dump it")); }
} Try / catch
match Layout::from_kdl(&stringified_layout, None, None, None) {
Ok(_) => proceed_with_switch(),
Err(e) => Err(anyhow!("Failed to deserialize layout: {e}")),
} Prevention
- Re-dump serialized layouts after every zellij upgrade instead of persisting blobs indefinitely
- Store layouts as files and re-read them at switch time rather than caching stringified copies
When it happens
Trigger: A plugin calls switch_session with LayoutInfo::Stringified containing KDL that zellij rejects (syntax error, unknown node, invalid values); or a session-layout blob captured by a different zellij version with incompatible syntax.
Common situations: Session-manager plugins switching to recorded sessions after a zellij upgrade changed layout syntax; hand-edited serialized session layouts; truncation/corruption of the stringified blob in plugin storage.
Related errors
- Failed to parse layout: {:?}
- Failed to serialize user configuration: {:?}
- failed to load plugin from disk
- Plugin is not stored in memory
- Failed to get running plugin
AI-assisted analysis of zellij-org/zellij@98a0837077 (2026-08-16).
Data as JSON: /api/errors/2c96861034841a82.
Report an issue: GitHub.