Hmbown/CodeWhale · error
rendered body
Error message
rendered body
What it means
This panic comes from `store.rendered_body().expect("rendered body")` at crates/config/src/tests.rs:4298. `rendered_body()` (crates/config/src/lib.rs:5569) validates configured models, serializes the config to pretty TOML, fixes the provider field, and merges comments back from the originally loaded raw text. It fails when validation rejects a value, TOML serialization fails, or `merge_and_preserve_comments` decides the original snapshot is unmergeable and cannot safely preserve it.
Solutions
- Fix the config value that fails validate_configured_models before rendering
- Reload the store so `original_raw` matches the current on-disk file
- If the merge is fundamentally unmergeable, fall back to a plain serialized body and accept comment loss
Example fix
// before
transaction.stage(&config_path, store.rendered_body().expect("rendered body").into_bytes());
// after
let body = store.rendered_body()
.map_err(|e| panic!("rendered body: {e:#}"))
.unwrap();
transaction.stage(&config_path, body.into_bytes()); Defensive patterns
Strategy: validation
Validate before calling
// validate configured models before rendering
codewhale_config::catalog::configured::validate_configured_models(
store.config().custom_models.as_deref().unwrap_or_default(),
).map_err(|e| format!("invalid custom models: {e}"))?; Try / catch
match store.rendered_body() {
Ok(body) => transaction.stage(&config_path, body.into_bytes()),
Err(e) => return Err(anyhow!("cannot render config body: {e:#}")),
} Prevention
- Fix invalid custom_models entries before saving
- Reload the store so original_raw matches disk before rendering
- Accept comment loss as a fallback when the merge is unmergeable
When it happens
Trigger: Calling `rendered_body()` on a store whose config contains entries failing `validate_configured_models`, whose serialization cannot be parsed back by toml_edit, or whose `original_raw` no longer structurally matches the serialized output.
Common situations: Custom models violating catalog validation rules; a loaded file that was mutated on disk after load; exotic TOML constructs that the comment-merge cannot reconcile with a fresh serialization.
Understand the failure class
Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.
Related errors
- Could not parse destination route; contents omitted
- Could not parse route configuration; contents omitted
- Could not parse switched route; contents omitted
- could not prepare imported configuration; contents omitted
- {err}
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/509f6f3d654e2279.
Report an issue: GitHub.
Appendix: source
Thrown at crates/config/src/tests.rs:4298
// #3410: the comment-preserving ConfigStore write must compose with
// SetupTransaction so a setup step can update config.toml atomically
// alongside sibling setup files.
let dir = tempfile::tempdir().expect("tempdir");
let config_path = dir.path().join(CONFIG_FILE_NAME);
let state_path = dir.path().join(crate::setup_state::SETUP_STATE_FILE_NAME);
fs::write(
&config_path,
"# my model\nmodel = \"deepseek-v4-flash\"\n# end comment\n",
)
.expect("write config");
let mut store = ConfigStore::load(Some(config_path.clone())).expect("load config store");
store.config.model = Some("deepseek-v4-pro".to_string());
let mut transaction = persistence::SetupTransaction::new();
transaction.stage(
&config_path,
store.rendered_body().expect("rendered body").into_bytes(),
);
transaction
.stage_json(&state_path, &SetupState::default())
.expect("stage setup state");
transaction.commit().expect("commit");
let body = fs::read_to_string(&config_path).expect("read config");
assert!(body.contains("# my model"), "prefix comment preserved");
assert!(body.contains("# end comment"), "suffix comment preserved");
assert!(body.contains("model = \"deepseek-v4-pro\""));
assert!(state_path.exists(), "sibling setup state written");
}
#[test]
fn setup_transaction_rolls_back_config_store_body_on_sibling_failure() {
// #3410 rollback expectation: when a sibling stage fails to apply, the
// already-written config.toml is restored byte-for-byte, comments and
// all — no half-applied setup.View on GitHub (pinned to 433685b202)