{"record":{"id":"a8bb7e9711b468ac","repo":"aaif-goose/goose","slug":"extension-state-serialization-failed","errorCode":null,"errorMessage":"Extension state serialization failed: {}","messagePattern":"Extension state serialization failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/goose/src/agents/agent.rs","lineNumber":1260,"sourceCode":"\n        (\n            request_id,\n            Ok(self.with_post_tool_hook(result, &tool_call, session)),\n        )\n    }\n\n    /// Save current extension state to session metadata\n    /// Should be called after any extension add/remove operation\n    pub async fn save_extension_state(&self, session: &SessionConfig) -> Result<()> {\n        let extensions_state =\n            EnabledExtensionsState::new(self.extension_configs_for_persistence().await);\n\n        let session_manager = self.config.session_manager.clone();\n        let mut session_data = session_manager.get_session(&session.id, false).await?;\n\n        if let Err(e) = extensions_state.to_extension_data(&mut session_data.extension_data) {\n            warn!(\"Failed to serialize extension state: {}\", e);\n            return Err(anyhow!(\"Extension state serialization failed: {}\", e));\n        }\n\n        session_manager\n            .update(&session.id)\n            .extension_data(session_data.extension_data)\n            .apply()\n            .await?;\n\n        Ok(())\n    }\n\n    /// Save current extension state to session by session_id\n    pub async fn persist_extension_state(&self, session_id: &str) -> Result<()> {\n        let extensions_state =\n            EnabledExtensionsState::new(self.extension_configs_for_persistence().await);\n\n        let session_manager = self.config.session_manager.clone();\n        let session = session_manager.get_session(session_id, false).await?;","sourceCodeStart":1242,"sourceCodeEnd":1278,"githubUrl":"https://github.com/aaif-goose/goose/blob/3810898a7447ec3299be72e223d3570a7aabf0ab/crates/goose/src/agents/agent.rs#L1242-L1278","documentation":"Agent::save_extension_state serializes the agent's current extension list as EnabledExtensionsState and writes it into the session's extension_data under key 'enabled_extensions.v0'. This error means serde failed to serialize the Vec<ExtensionConfig> itself (to_extension_data -> to_value), before any storage write happened.","triggerScenarios":"An ExtensionConfig variant currently loaded in the agent cannot be represented as JSON — e.g. a serde tag/shape mismatch after a goose upgrade changed the ExtensionConfig enum, or an extension config constructed programmatically with non-serializable content.","commonSituations":"Upgrading goose while sessions hold extension configs of the old shape and then calling save_extension_state on a code path that still uses old configs; custom-built extensions with unserializable fields; config migrations that leave a legacy variant in memory.","solutions":["Identify the recently added/changed extension — serialize each ExtensionConfig individually to find the offender","Update goose so the in-memory ExtensionConfig enum and serializer agree","Remove the offending extension and retry the save","If the session's stored state is corrupt, start a fresh session rather than fighting the old one"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// probe-serialize before saving so the failing extension is identifiable:\nfor ext in agent.extension_configs_for_persistence().await {\n    if serde_json::to_value(&ext).is_err() {\n        tracing::error!(\"unserializable extension config: {:?}\", ext);\n    }\n}","typeGuard":"fn extension_state_serialization_failed(e: &anyhow::Error) -> bool {\n    e.to_string().contains(\"Extension state serialization failed\")\n}","tryCatchPattern":"if let Err(e) = agent.save_extension_state(&session).await {\n    if extension_state_serialization_failed(&e) {\n        // keep the session running; flag the offending extension for removal\n        tracing::error!(\"extension state not saved: {e}\");\n    } else {\n        return Err(e);\n    }\n}","preventionTips":["Keep goose and extensions version-aligned","Test add/remove extension flows after upgrades","Remove extensions that fail serialization instead of retrying blindly"],"tags":["rust","goose","extensions","serialization","session"],"backgroundTag":null,"analyzedSha":"3810898a7447ec3299be72e223d3570a7aabf0ab","analyzedAt":"2026-08-16T10:14:26.282Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}