{"record":{"id":"124c2f4ba78877bf","repo":"openai/codex","slug":"failed-to-parse-app-config-for-selected-plugin-p","errorCode":null,"errorMessage":"failed to parse app config for selected plugin `{plugin_id}` at `{path}`: {source}","messagePattern":"failed to parse app config for selected plugin `(.+?)` at `(.+?)`: (.+?)","errorType":"exception","errorClass":"ExecutorPluginConnectorProviderError","httpStatus":null,"severity":"error","filePath":"codex-rs/ext/connectors/src/executor_plugin.rs","lineNumber":24,"sourceCode":"use codex_utils_path_uri::PathUri;\nuse std::io;\nuse thiserror::Error;\n\n/// Loads connector declarations from a resolved plugin through its owning executor.\n#[derive(Clone, Copy, Debug, Default)]\npub struct ExecutorPluginConnectorProvider;\n\n/// Failure to load connector declarations from an executor plugin.\n#[derive(Debug, Error)]\npub enum ExecutorPluginConnectorProviderError {\n    #[error(\"failed to read app config for selected plugin `{plugin_id}` at `{path}`: {source}\")]\n    ReadConfig {\n        plugin_id: String,\n        path: PathUri,\n        #[source]\n        source: io::Error,\n    },\n    #[error(\"failed to parse app config for selected plugin `{plugin_id}` at `{path}`: {source}\")]\n    ParseConfig {\n        plugin_id: String,\n        path: PathUri,\n        #[source]\n        source: serde_json::Error,\n    },\n}\n\nimpl ExecutorPluginConnectorProvider {\n    /// Returns the connector declarations contributed by `plugin`.\n    #[tracing::instrument(name = \"connectors.executor_plugin.declarations.load\", skip_all)]\n    pub async fn load(\n        &self,\n        plugin: &ResolvedExecutorPlugin,\n    ) -> Result<Vec<AppDeclaration>, ExecutorPluginConnectorProviderError> {\n        let resolved_plugin = plugin.plugin();\n        let plugin_id = resolved_plugin.selected_root_id();\n        let Some(PluginResourceLocator::Environment {","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/openai/codex/blob/339751715c64496cb86246bfb3935f40e309dd3d/codex-rs/ext/connectors/src/executor_plugin.rs#L6-L42","documentation":"The plugin's apps config file was read successfully but parse_plugin_app_config (serde_json) could not deserialize its contents into AppDeclaration values. The serde_json::Error source gives the exact line/column of the problem. This is a plugin packaging bug or a host/plugin schema version mismatch, not an environment issue.","triggerScenarios":"ExecutorPluginConnectorProvider::load on a plugin whose apps config is not valid JSON (trailing commas, comments, BOM) or whose structure does not match the expected app declaration schema (missing required fields, wrong types).","commonSituations":"Hand-edited apps config saved as JSONC/JSON5; plugin built against a newer or older declaration schema than the running host; empty file where an object was expected.","solutions":["Validate the file at the printed path with a JSON parser (jq . apps.json) and fix the reported syntax error.","Diff the document's shape against a known-good plugin's apps config.","Update the plugin to a version matching the host's codex-connectors schema, or update the host.","Add a CI step that serde-parses the config before packaging the plugin."],"exampleFix":"// before (apps.json) — trailing comma\n{ \"apps\": [ { \"id\": \"db\", \"commands\": \"...\" , ] }\n\n// after\n{ \"apps\": [ { \"id\": \"db\", \"commands\": \"...\" } ] }","handlingStrategy":"validation","validationCode":"// Fail fast before host startup if the apps config is not even valid JSON\nlet raw = std::fs::read_to_string(&apps_config_path)?;\nserde_json::from_str::<serde_json::Value>(&raw)\n    .map_err(|e| anyhow::anyhow!(\"invalid apps config {apps_config_path}: {e}\"))?;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Add a serde round-trip of the apps config to the plugin's CI.","Pin plugin and host versions so declaration schemas stay aligned.","Reject JSONC-style edits (comments, trailing commas) via a pre-commit JSON check."],"tags":["rust","plugin","json","serde","codex"],"backgroundTag":"config-json-parse-error","analyzedSha":"339751715c64496cb86246bfb3935f40e309dd3d","analyzedAt":"2026-08-25T05:35:09.876Z","schemaVersion":2},"datasetVersion":"2026-08-25T06:17:31.827Z"}