{"record":{"id":"ec75c5b8fcda5937","repo":"zeroclaw-labs/zeroclaw","slug":"config-at-does-not-deserialize-strictly-the-re","errorCode":null,"errorMessage":"config at {} does not deserialize strictly; the resilient loader is substituting defaults for the failing section. Parse error: {error}","messagePattern":"config at (.+?) does not deserialize strictly; the resilient loader is substituting defaults for the failing section\\. Parse error: (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/main.rs","lineNumber":5812,"sourceCode":"                                \"migrated\": false,\n                                \"schema_version\": crate::config::migration::CURRENT_SCHEMA_VERSION,\n                                \"valid\": strict_error.is_none(),\n                                \"error\": strict_error,\n                            });\n                            println!(\"{}\", serde_json::to_string_pretty(&envelope)?);\n                            if strict_error.is_some() {\n                                std::process::exit(1);\n                            }\n                        } else {\n                            println!(\n                                \"{}\",\n                                t(\n                                    \"cli-config-schema-current\",\n                                    \"Config already at current schema version.\"\n                                )\n                            );\n                            if let Some(error) = strict_error {\n                                anyhow::bail!(\n                                    \"config at {} does not deserialize strictly; the resilient \\\n                                     loader is substituting defaults for the failing section. \\\n                                     Parse error: {error}\",\n                                    config.config_path.display()\n                                );\n                            }\n                        }\n                    }\n                }\n                Ok(())\n            }\n            ConfigCommands::Patch { input, json } => {\n                crate::config::migration::ensure_disk_at_current_version(&config.config_path)?;\n                let body = match input.as_deref() {\n                    None | Some(\"-\") => {\n                        use std::io::Read;\n                        let mut buf = String::new();\n                        if let Err(err) = std::io::stdin().read_to_string(&mut buf) {","sourceCodeStart":5794,"sourceCodeEnd":5830,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/src/main.rs#L5794-L5830","documentation":"Thrown by `zeroclaw config migrate` after it finds the file already at the current schema version (migrate_file_in_place returned None) but a strict re-parse via config::migration::migrate_to_current still fails. ZeroClaw loads config.toml with a resilient loader that substitutes default values for any section that fails to deserialize, so the config the process actually runs with can differ from disk; this error surfaces that divergence instead of letting it pass silently.","triggerScenarios":"Running `zeroclaw config migrate` (non-JSON output) when the on-disk file has a section whose types or field names violate the current schema — e.g. `enabled = \"yes\"` where a bool is expected, a renamed key, or a wrongly typed value from a hand-merged TOML. The version marker is already current so no migration runs; the strict parse error is re-checked and reported.","commonSituations":"Hand-editing config.toml right after upgrading ZeroClaw; resolving a git/dotfiles merge conflict by hand; copying sections from older release notes, another machine, or community examples whose shape no longer matches; automation writing TOML with wrongly typed values.","solutions":["Run `zeroclaw config migrate --json` and read the `error` field — it names the exact section, key, and serde reason for the failure","Fix the named key in config.toml to match the schema (print the full schema with `zeroclaw config schema`)","Re-run `zeroclaw config migrate` until it prints 'Config already at current schema version.' without the bail","Restart the daemon/gateway and any long-running agent so they reload the corrected file — their previous in-memory config contained substituted defaults for the broken section"],"exampleFix":"# before\n[security.estop]\nenabled = \"yes\"\n# after\n[security.estop]\nenabled = true","handlingStrategy":"validation","validationCode":"# CI pre-deploy gate: strict-parse the config the target will load\nzeroclaw config migrate --json | jq -e '.valid == true' >/dev/null || {\n  echo \"config.toml fails strict deserialization\"; exit 1;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run `zeroclaw config migrate --json` in CI on every config change instead of trusting the resilient loader","Edit config through `zeroclaw config set` / `config init` so values are written in schema shape","Keep config.toml in git and review diffs for type drift after upgrades","Never paste whole sections from other versions; add keys one at a time and re-validate"],"tags":["config","toml","serde","schema","zeroclaw","cli"],"backgroundTag":"config-schema-validation-failed","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}