zeroclaw-labs/zeroclaw · error · anyhow::Error
config at {} does not deserialize strictly; the resilient lo
Error message
config at {} does not deserialize strictly; the resilient loader is substituting defaults for the failing section. Parse error: {error} What it means
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.
Source
Thrown at src/main.rs:5812
"migrated": false,
"schema_version": crate::config::migration::CURRENT_SCHEMA_VERSION,
"valid": strict_error.is_none(),
"error": strict_error,
});
println!("{}", serde_json::to_string_pretty(&envelope)?);
if strict_error.is_some() {
std::process::exit(1);
}
} else {
println!(
"{}",
t(
"cli-config-schema-current",
"Config already at current schema version."
)
);
if let Some(error) = strict_error {
anyhow::bail!(
"config at {} does not deserialize strictly; the resilient \
loader is substituting defaults for the failing section. \
Parse error: {error}",
config.config_path.display()
);
}
}
}
}
Ok(())
}
ConfigCommands::Patch { input, json } => {
crate::config::migration::ensure_disk_at_current_version(&config.config_path)?;
let body = match input.as_deref() {
None | Some("-") => {
use std::io::Read;
let mut buf = String::new();
if let Err(err) = std::io::stdin().read_to_string(&mut buf) {View on GitHub (pinned to 88bb9c8533)
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
Example fix
# before [security.estop] enabled = "yes" # after [security.estop] enabled = true
Defensive patterns
Strategy: validation
Validate before calling
# CI pre-deploy gate: strict-parse the config the target will load
zeroclaw config migrate --json | jq -e '.valid == true' >/dev/null || {
echo "config.toml fails strict deserialization"; exit 1;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Emergency stop is disabled. Enable [security.estop].enabled
- embedding route "{}" has empty model
- embedding route "{}" has invalid dimensions=0
- unsupported room visibility '{other}': expected private or p
- channel '{}' does not support forge API requests
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/ec75c5b8fcda5937.
Report an issue: GitHub.